首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么“反对派”支持“`IntoIterator`”?

为什么“反对派”支持“`IntoIterator`”?
EN

Stack Overflow用户
提问于 2017-04-07 19:03:24
回答 1查看 1.6K关注 0票数 16

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

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

代码语言:javascript
复制
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);
    }
}
代码语言:javascript
复制
error[E0308]: mismatched types
  --> src/main.rs:11:18
   |
11 |         take_str(&s); // Type mismatch: found type `&&[std::string::String]`
   |                  ^^ expected `str`, found `&[String]`
   |
   = note: expected reference `&str`
              found reference `&&[String]`

我原以为s会是String,但实际上是&[String]。这是因为我的for循环正在迭代Vec::get()返回的Option

我还编写了以下代码,它演示了for循环实际上正在展开一个Option

代码语言:javascript
复制
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上迭代有什么用例

EN

回答 1

Stack Overflow用户

发布于 2017-04-07 19:07:53

Option上迭代有什么用例?

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

代码语言:javascript
复制
fn main() {
    let results = [Some(1), None, Some(3), None];
    let sum: i32 = results.into_iter().flatten().sum();
    println!("{}", sum)
}

在锈蚀1.29之前,您可以使用flat_map

代码语言:javascript
复制
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参与更大份额的API。

注意,出于类似的原因,IntoIterator也是为Result实现的。

这真是令人难以置信的困惑

是的,这就是为什么克里皮有一根皮棉

代码语言:javascript
复制
warning: for loop over `str_vec.get(0..3)`, which is an `Option`. This is more readably written as an `if let` statement
  --> src/main.rs:10:14
   |
10 |     for s in str_vec.get(0..3) {
   |              ^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(clippy::for_loops_over_fallibles)]` on by default
   = help: consider replacing `for s in str_vec.get(0..3)` with `if let Some(s) = str_vec.get(0..3)`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#for_loops_over_fallibles

这表明,对于程序员来说,Option不像容器是有办法的。

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43285372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档