Option <Vec <>>上的迭代器

Xav*_* T. 2 rust

我正在尝试继续Option<Vec<>>.

#[derive(Debug)]
pub struct Person {
    pub name: Option<String>,
    pub age: Option<u64>,
}

#[derive(Debug)]
pub struct Foo {
    pub people: Option<Vec<Person>>,
}
Run Code Online (Sandbox Code Playgroud)

天真的我正在使用

for i in foo.people.iter() {
    println!("{:?}", i);
}
Run Code Online (Sandbox Code Playgroud)

Vec我没有遍历所有元素,而是实际显示整体Vec.这就像我在迭代唯一的参考Option.

使用以下内容,我正在迭代Vec内容:

for i in foo.people.iter() {
    for j in i.iter() {
        println!("{:?}", j);
    }
}
Run Code Online (Sandbox Code Playgroud)

我不确定这是最令人愉快的语法,我相信你应该解开第Option一个实际迭代的集合.

Option::iter如果你总是有一个参考,那么我看不到你实际可以使用的地方.

是游乐场的链接.

Luk*_*oid 11

正如对另一个答案的评论中所述,我将使用以下内容:

// Either one works
foo.people.iter().flatten()
foo.people.iter().flat_map(identity)
Run Code Online (Sandbox Code Playgroud)

iter上方法Option<T>将返回一个或零个元素的迭代器。

flatten获取每个元素(在本例中&Vec<Person>)并展平它们的嵌套元素。

flat_map与 with相同identity,它接受每个元素(在本例中为&Vec<Person>)并展平它们的嵌套元素。

两条路径都会产生一个Iterator<Item = &Person>.


She*_*ter 6

使用Option::as_derefOption::unwrap_or_default

for i in foo.people.as_deref().unwrap_or_default() {
    println!("{:?}", i);
}
Run Code Online (Sandbox Code Playgroud)

Option::as_deref转换&Option<Vec<T>>Option<&[T]>,然后unwrap_or_default返回该值&[T]或默认值(一个空切片)。然后您可以直接迭代它。

也可以看看:


use*_*342 5

Option有一个iter方法 "迭代可能包含的值",即提供Option(如果选项是Some)中的单个值,或根本没有提供任何值(如果选项是None).因此,如果您希望将选项视为容器,这None意味着容器为空并且Some意味着它包含单个元素.

要迭代底层元素的值,您需要切换foo.people.iter()到其中一个foo.people.unwrap().iter()或者foo.people.unwrap_or_else(Vec::new).iter(),这取决于您是否希望程序在遇到None人时发生恐慌或不迭代.

在操场上可编辑的例子.

  • @Lukazoid 不需要`v.iter()`;只是 `v` 会起作用。 (5认同)
  • 如果让一些(ref v)= foo.people {}`围绕迭代,而不是`unwrap`,也可以简单地包装` (2认同)
  • 如果我一直想迭代那些人,我可能会做`foo.people.iter().flat_map(| v | v.iter())`,`None`会给出一个空的迭代器,否则我们会给所有的向量的元素. (2认同)