我正在学习 Rust。 我的理解 : iter() :集合内数据的只读视图。 into_iter() :集合内数据的可写和可读视图。 (警告:完全访问权限,但从父范围移动) iter_mut() :集合内数据的可写视图。 (警告:完全访问但未从父范围移出,类似于其他 gc 收集的语言) 为了区分从 iter() 和 iter_mut() 返回的数据类型,我们使用 &"Ferris" 和 &mut"Ferris"
工作代码:
fn main() {
let mut names = vec!["Bob", "Frank", "Ferris"];
for name in names.iter_mut() {
*name = match name {
&mut "Ferris" => "There is a rustacean among us!",
_ => "Hello!",
}
}
println!("names: {:?}", names);
}
为什么下面的代码不起作用。
fn main() {
let names = vec!["Bob", "Frank", "Ferris"];
for name in names.into_iter() {
*name = match name {
"Ferris" => "There is a rustacean among us!",
_ => "Hello",
};
println!("names: {:?}", names);
}
}
错误:
编译playground v0.0.1 (/playground) 错误[E0308]:类型不匹配 src/main.rs:6:25 | 6 | "Ferris" => "我们中间有一只锈类动物!", 预期
,发现str
&str
错误[E0277]:编译时无法知道
类型值的大小 src/main.rs:5:9 | 5 | *名称=匹配名称{ 编译时没有已知的大小 | 帮助:特征str
未针对Sized
实现 注意:作业的左侧必须具有静态已知的大小str
部分错误有详细解释:E0277、E0308。 有关错误的更多信息,请尝试
。 错误:由于之前的 2 个错误,无法编译rustc --explain E0277
(bin“playground”)playground
我尝试在 match 语句中使用 to_string() 将 &str 更改为 String,但不清楚为什么此代码不起作用。
类型因迭代而异。 特别是
name in names.into_iter()
不会为您提供可变引用,而是集合 names
内的类型,即 &str
。
以下代码[playground]:
fn type_name<T>(_t: &T) -> &'static str {
std::any::type_name::<T>()
}
fn main() {
let mut names = vec!["Bob", "Frank", "Ferris"];
for name in names.iter_mut() {
println!("names: {:?} -> {}", name, type_name(&name));
}
for name in names.iter() {
println!("names: {:?} -> {}", name, type_name(&name));
}
for name in names.into_iter() {
println!("names: {:?} -> {}", name, type_name(&name));
}
}
会给你:
names: "Bob" -> &mut &str
names: "Frank" -> &mut &str
names: "Ferris" -> &mut &str
names: "Bob" -> &&str
names: "Frank" -> &&str
names: "Ferris" -> &&str
names: "Bob" -> &str
names: "Frank" -> &str
names: "Ferris" -> &str
要了解错误,您可以查看类型,
names
是从字符串文字创建的Vec
,因此它的类型是Vec<&'static str>
。现在它的 into_iter()
迭代器的项是 &'static str
,当您尝试取消引用它时,即像您的代码尝试那样写入 *name
,它必须取消引用 &'static str
,结果是 str
是一个未调整大小的类型!您可以改为写入 name
但您必须使其绑定可变,当然 into_iter
会移动它的接收器,即向量,因此您在调用后 cannot 打印它,因此结果不会执行所有这些操作很多:
fn main() {
let names = vec!["Bob", "Frank", "Ferris"];
for mut name in names.into_iter() {
name = match name {
"Ferris" => "There is a rustacean among us!",
_ => "Hello",
};
}
}