我试图迭代字符串向量的子部分,即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
?
答案 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
不的方式就像程序员的容器一样。