diff options
author | Bryan Newbold <bnewbold@archive.org> | 2019-05-19 22:09:30 -0700 |
---|---|---|
committer | Bryan Newbold <bnewbold@archive.org> | 2019-05-19 22:10:28 -0700 |
commit | 8c51b17ef7176de9ca7afdb5f1d51dd3905ba555 (patch) | |
tree | ae2f40898774a969019d349631e1e8be4014c39c /software | |
parent | 04858ed7e251227e70a7105c8197abb194b6195a (diff) | |
download | knowledge-8c51b17ef7176de9ca7afdb5f1d51dd3905ba555.tar.gz knowledge-8c51b17ef7176de9ca7afdb5f1d51dd3905ba555.zip |
rust Option/Result map() tricks
Diffstat (limited to 'software')
-rw-r--r-- | software/rust.page | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/software/rust.page b/software/rust.page index df99de4..4e8aa44 100644 --- a/software/rust.page +++ b/software/rust.page @@ -3,9 +3,10 @@ Rust ## Resources -- [http://xion.io/post/code/rust-iter-patterns.html]() -- [https://deterministic.space/rust-cli-tips.html]() -- [https://manishearth.github.io/blog/2018/01/10/whats-tokio-and-async-io-all-about/]() +- <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. @@ -22,3 +23,40 @@ Run tests with stdout output: 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)?), + }, + }; + |