Skip to content

Commit 3d748b1

Browse files
authored
Merge pull request #25 from lfairy/option-list
Add "Treating Option like a list"
2 parents a65d22d + f3fe2d6 commit 3d748b1

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ language.
1919
* TODO leak amplification ("Vec::drain sets the Vec's len to 0 prematurely so that mem::forgetting Drain "only" mem::forgets more stuff. instead of exposing uninitialized memory or having to update the len on every iteration")
2020
* [Finalisation in destructors](idioms/dtor-finally.md)
2121
* TODO interior mutability - UnsafeCell, Cell, RefCell
22-
* TODO treating Option like a list
22+
* [Iterating over an `Option`](idioms/option-iter.md)
2323
* TODO `Default` trait
2424
* [Pass variables to closure](idioms/pass-var-to-closure.md)
2525

idioms/option-iter.md

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Iterating over an `Option`
2+
3+
## Description
4+
5+
`Option` can be viewed as a container that contains either zero or one elements. In particular, it implements the `IntoIterator` trait, and as such can be used with generic code that needs such a type.
6+
7+
## Examples
8+
9+
Since `Option` implements `IntoIterator`, it can be used as an argument to [`.extend()`](https://doc.rust-lang.org/std/iter/trait.Extend.html#tymethod.extend):
10+
11+
```rust
12+
let turing = Some("Turing");
13+
let mut logicians = vec!["Curry", "Kleene", "Markov"];
14+
15+
logicians.extend(turing);
16+
17+
// equivalent to
18+
if let Some(turing_inner) = turing {
19+
bar.push(turing_inner);
20+
}
21+
```
22+
23+
If you need to tack an `Option` to the end of an existing iterator, you can pass it to [`.chain()`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.chain):
24+
25+
```rust
26+
let turing = Some("Turing");
27+
let logicians = vec!["Curry", "Kleene", "Markov"];
28+
29+
for logician in logicians.iter().chain(turing.iter()) {
30+
println!("{} is a logician", logician);
31+
}
32+
```
33+
34+
Note that if the `Option` is always `Some`, then it is more idiomatic to use [`std::iter::once`](https://doc.rust-lang.org/std/iter/fn.once.html) on the element instead.
35+
36+
Also, since `Option` implements `IntoIterator`, it's possible to iterate over it using a `for` loop. This is equivalent to matching it with `if let Some(..)`, and in most cases you should prefer the latter.
37+
38+
## See also
39+
40+
* [`std::iter::once`](https://doc.rust-lang.org/std/iter/fn.once.html) is an iterator which yields exactly one element. It's a more readable alternative to `Some(foo).into_iter()`.
41+
42+
* [`Iterator::filter_map`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter_map) is a version of [`Iterator::flat_map`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.flat_map), specialized to mapping functions which return `Option`.
43+
44+
* The [`ref_slice`](https://crates.io/crates/ref_slice) crate provides functions for converting an `Option` to a zero- or one-element slice.
45+
46+
* [Documentation for `Option<T>`](https://doc.rust-lang.org/std/option/enum.Option.html)

0 commit comments

Comments
 (0)