Rust 错误:编译时没有已知的大小

问题描述 投票:0回答:2

我正在学习 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]:编译时无法知道

str
类型值的大小 src/main.rs:5:9 | 5 | *名称=匹配名称{ 编译时没有已知的大小 | 帮助:特征
Sized
未针对
str
实现 注意:作业的左侧必须具有静态已知的大小

部分错误有详细解释:E0277、E0308。 有关错误的更多信息,请尝试

rustc --explain E0277
。 错误:由于之前的 2 个错误,无法编译
playground
(bin“playground”)

我尝试在 match 语句中使用 to_string() 将 &str 更改为 String,但不清楚为什么此代码不起作用。

rust compilation size compile-time
2个回答
0
投票

类型因迭代而异。 特别是

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

0
投票

要了解错误,您可以查看类型,

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",
        };
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.