bool::then_some
in RustWhile participating in Advent of Code, I learned about bool::then_some
. Because I tried to finish the problem on time, I did not read fully the documentation. I wrote a get
helper function to access an element in a 2D array. The code (simplified to 1D) looked like:
fn main() {
dbg!(get(&vec![42, 51], 4));
}
fn get(v: &[u8], i: usize) -> Option<u8> {
(i < v.len()).then_some(v[i])
}
It compiles fine, but it crashes:
thread 'main' panicked at src/main.rs:6:29:
index out of bounds: the len is 2 but the index is 4
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Cargo-Process exited abnormally with code 101 at Thu Feb 13 21:04:58
What is wrong with this code?
bool::then
in RustWhen the get
function runs, regardless of the bound check, v[i]
is eagerly evaluated (as it is an argument of the then_some
function). That’s why bool::then
exists; it relies on lazy evaluation via a lambda.
The below get
function will not crash due to index out of bounds:
fn get(v: &[u8], i: usize) -> Option<u8> {
(i < v.len()).then(|| v[i])
}
Note, this pattern is used in several places. As similar an example, consider Option::unwrap_or
and Option::unwrap_or_else
.
Finally, this is the real use case I stumbled upon while solving day 12 of Advent Of Code 2024.