为什么`Option`支持`IntoIterator`?

时间:2017-04-07 19:03:25

标签: foreach rust optional

我试图迭代字符串向量的子部分,即Vec<String>的子部分。在每次迭代中,我想将字符串作为切片传递给函数。

我没有注意到Vec::get返回Option,并认为我可以直接迭代返回值:

fn take_str(s: &str) {
    println!("{}", s);
}

fn main() {
    let str_vec: Vec<String> =
        ["one", "two", "three", "uno", "dos", "tres"].iter().map(|&s| 
        s.into()).collect();
    for s in str_vec.get(0..3) {
        take_str(&s); // Type mismatch: found type `&&[std::string::String]`
    }
}

显然,我期待s成为String,但它实际上是&[String]。这是因为我的for循环实际上正在迭代Option返回的Vec::get()

我还编写了以下代码,该代码表明for循环实际上是展开Option

let foo = Option::Some ( ["foo".to_string()] );
for f in foo {
    take_str(&f); // Same error as above, showing `f` is of type `&[String]`
}

但这令人难以置信的混乱;我没想到(直到我编写这段代码并弄清楚它实际上在做什么),Option可以通过迭代来解开它。为什么支持?迭代Option

的用例是什么?

1 个答案:

答案 0 :(得分:13)

  

有什么用例可以迭代Option

总之,我最喜欢的原因是flat_map

fn main() {
    let results = vec![Some(1), None, Some(3), None];
    let sum: i32 = results.into_iter().flat_map(|x| x).sum();
    println!("{}", sum)
}

Option可以被认为是一个可以容纳零个或一个元素的容器。将其与Vec进行比较,Option可以包含零个或多个元素。在很多方面,Vec 就像IntoIterator一样!

实施Option允许IntoIterator参与更多的API。

请注意Result warning: for loop over `str_vec.get(0..3)`, which is an `Option`. This is more readably written as an `if let` statement. 实施,原因类似。

  

但这令人难以置信的混乱

是的,这就是Clippy has a lint for it

的原因
Option

这表明$link 的方式就像程序员的容器一样。