Learning Rust, Part 5
foon.uk
foon.uk
This isn't really a blog or a tutorial, it's just me stumbling around and trying stuff. I enjoy reading this sort of thing when other people do it, so I hope you get something out of it too.
Previously: https://news.ycombinator.com/item?id=8546546
AFAIK, the Rust people haven't said that for quite some time. There are still a number of unstable area (the most annoying to me being benchmarking) but by and large stable is very much usable.
In your case, the code could be simplified (and would work on stable) by using a bytes iterator (and an actual for loop):
fn main() {
let mut state = mkstate();
for it in stdin().bytes() {
update(&mut state, it.unwrap());
draw(&state);
}
}
replace a few `char` by `u8` and change key_dir to: match input {
b'h' => Coord(-1, 0),
b'j' => Coord(0, 1),
b'k' => Coord(0, -1),
b'l' => Coord(1, 0),
_ => Coord(0, 0)
}
(I used unwrap because the stdin errors are not handled anyway, might as well panic)edit: conventionally, when structures aren't "raw" they're initialised via a `new()` method, so `mkstate` would usually be `impl State { fn new() -> State { … } }`.
And derive(Default) is necessary because, well, you're using default values for your structs. From what I've seen that's mostly done when partial overrides of default value makes sense (`Struct { f: v, ..Default::default() }` will fill any value which isn't provided by whatever's in `Default`) which isn't the case here.
You could get rid of it by implementing initialisations explicitly, something along the lines of:
impl State {
fn new() -> State {
let mut state = State {
// or add a new() on them as well
position: position::State { objects: Vec::new() },
graphics: graphics::State { objects: Vec::new() }
};
mktest(&mut state, 42, Coord(1, 1), '@');
mktest(&mut state, 57, Coord(8, 8), '$');
state
}
}
I'd also suggest deriving Copy on Coord (makes the structure "pass by copy" rather than "pass by move", so you don't have to clone it explicitly).And you could `impl Add for Coord` to replace `vadd(old_position, dir)` by `old_position + dir`
(I believe Rust code also tends to use more methods, but I'm guessing you like free functions).
You could also replace the inner State structs by type aliases, the struct doesn't seem to have much value, so
mod graphics {
pub struct State {
pub objects: Vec<Sprite>
}
}
=> mod graphics {
pub type State = Vec<Sprite>
}
and remove the indirections through `objects` (and you get a "free new" on graphics::State and position::State as they're now just aliases for Vec<_>) fn process(state: &State)
still has a recursive call after it's been converted to use a loop.