我试图迭代字符串向量的一个分段,即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);
}
}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
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上迭代有什么用例
发布于 2017-04-07 19:07:53
在
Option上迭代有什么用例?
总之,我最喜欢的原因是flatten
fn main() {
let results = [Some(1), None, Some(3), None];
let sum: i32 = results.into_iter().flatten().sum();
println!("{}", sum)
}在锈蚀1.29之前,您可以使用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参与更大份额的API。
注意,出于类似的原因,IntoIterator也是为Result实现的。
这真是令人难以置信的困惑
是的,这就是为什么克里皮有一根皮棉
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不像容器是有办法的。
https://stackoverflow.com/questions/43285372
复制相似问题