software/rust
Rust
Resources
- http://xion.io/post/code/rust-iter-patterns.html
- https://deterministic.space/rust-cli-tips.htm
- https://manishearth.github.io/blog/2018/01/10/whats-tokio-and-async-io-all-about/
- https://saghm.github.io/five-rust-things/
Optimization: use RUSTFLAGS="-C target-cpu=native"
to take advantage of CPU special features.
(via http://vfoley.xyz/rust-compilation-tip/)
For local rust/std documentation, do rustup doc
.
Little tricks
Run tests with stdout output:
cargo test -- --nocapture
To run tests with logging enabled (eg, with env_logger
), make sure you add env_logger::init()
to the test function itself.
map() and Result Ergonomics
.collect()
has some magical features! In addition to turning an iterator of Item
into Vec<Item>
, it will turn an iterator of Result<Item>
into Result<Vec<Item>>
. This makes it really useful for the end of functions.
This is particularly useful for resolving some categories of “error handling in map closures”: you can use ?
in the map closure as long as you wrap the happy path with Ok()
and call collect on the outside. Eg:
let list: Vec<Item> = junk
.iter()
.map(|thing| Ok(Item {
a: thing.a,
b: fixup(thing.widget)?,
}))
.collect::Result<Vec<Item>>()?;
What about when map
over an Option
? Eg:
let toy = Shiny {
a: 123,
b: component.map(|v| paint(v).expect("paint to succeed"),
};
Should use match in this case:
let toy = Shiny {
a: 123,
b: match component {
None => None,
Some(v) => Some(paint(v)?),
},
};