summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Newbold <bnewbold@archive.org>2019-05-19 22:09:30 -0700
committerBryan Newbold <bnewbold@archive.org>2019-05-19 22:10:28 -0700
commit8c51b17ef7176de9ca7afdb5f1d51dd3905ba555 (patch)
treeae2f40898774a969019d349631e1e8be4014c39c
parent04858ed7e251227e70a7105c8197abb194b6195a (diff)
downloadknowledge-8c51b17ef7176de9ca7afdb5f1d51dd3905ba555.tar.gz
knowledge-8c51b17ef7176de9ca7afdb5f1d51dd3905ba555.zip
rust Option/Result map() tricks
-rw-r--r--software/rust.page44
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)?),
+ },
+ };
+