我试图迭代字符串向量的一个子部分,即 Vec<String>
的子切片。在每次迭代中,我想把字符串作为 slice 传递给一个函数。
我没有注意到 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
有什么用例吗?
遍历选项(Option)中的值
当你有一个Option
类型的值,并想要操作其中包含的值时,你需要先将其解包。但这样做可能会引发一些问题,例如值不存在的情况。更好的方式是使用iter
方法来遍历Option
中的值。let option_value: Option = Some(42);
for value in option_value.iter() {
println!("The value is: {}", value);
}
当option_value
是None
时,上述代码不会产生任何输出。如果你使用for
循环来遍历Option
的话,编译器会在代码中加入一些特殊的处理逻辑,以确保只有当值存在时才会执行循环体。如果你希望在值不存在时执行一些特殊的操作,可以使用if let
或match
表达式来处理。let option_value: Option = None;
if let Some(value) = option_value {
println!("The value is: {}", value);
} else {
println!("There is no value!");
}
上述代码会输出:There is no value!
- Josh Lee