我是Rust(1.31)的新手,我想了解一段不可编译的简单代码:

fn main() {
    s = String::from("foo");
    match s {
        "foo" => {
            println!("Yes");
        }
        _ => {
            println!("No");
        }
    }
}

相关错误为:

10 |         "foo" => {                                                                                 
   |         ^^^^^ expected struct `std::string::String`, found reference

在这个错误之后,我决定将代码更改为:

fn main() {
    let s = String::from("foo");

    match s {
        String::from("foo") => {
            println!("Yes");
        }
        _ => {
            println!("No");
        }
    }
}

通过这样做,我希望得到正确的类型,但事实并非如此:

10 |         String::from("foo") => {                                                                   
   |         ^^^^^^^^^^^^^^^^^^^ not a tuple variant or struct

我对来自编译器的这条消息感到非常困惑,最后我实现了:

fn main() {
    let s = String::from("foo");

    match &s as &str {
        "foo" => {
            println!("Yes");
        }
        _ => {
            println!("No");
        }
    }
}

然而,我不理解使这个解决方案成为正确解决方案的潜在机制,以及为什么我的第二个示例不起作用.

推荐答案

第一个示例不起作用,因为s属于String类型,这是一个拥有其中数据的字符串变量.它与字符串文本(可以用作类型&str)匹配.match不知道如何比较这两种不同的类型,所以它会出错.

然而,通过实现Deref<Target=str>String解除对&str的引用,这意味着在需要&str的情况下,可以使用对String的引用,例如,用于将其与1进行比较.第三个例子就是这样.通过创建引用&s,可以实现隐式deref,并且这两种类型具有可比性.

通过使用显式方法从String中创建&str,你可以用更少的魔法实现同样的事情:

fn main() {
    let s = String::from("foo");

    match s.as_str() {
        "foo" => {
            println!("Yes");
         },
         _ => {
             println!("No");
         }
    }
}

第二个例子试图使事物具有可比性,使String成为普通类型,而不是&str.它不起作用,因为match希望左侧有一个模式,而不是一个创建新 struct 的函数调用(也在后台进行分配).即使它可以工作(例如,通过将String创建移到匹配之外),这种方法也不太可取,因为新的String将需要内存分配.

Rust相关问答推荐

为什么函数不接受选项T参数的所有权?

将内部类型作为参数的泛型 struct 上的方法

当第二个`let`依赖于第一个`let()`时,如何在一行中有多个`let()`?

铁 rust 中的共享对象实现特征

Rust&;Tokio:如何处理更多的信号,而不仅仅是SIGINT,即SIGQUE?

在Rust 中移动原始指针的靶子安全吗

允许 rust 迹 struct 条目具有多种类型

如何将 struct 数组放置在另一个 struct 的末尾而不进行内存分段

在 Rust 中,为什么 10 个字符的字符串的 size_of_val() 返回 24 个字节?

`use` 和 `crate` 关键字在 Rust 项目中效果不佳

在描述棋盘时如何最好地使用特征与枚举

Rust中是否可以在不复制的情况下从另一个不可变向量创建不可变向量?

Rust与_有何区别?

Rust 中 Mutex<> 的深拷贝?

LinkedList::drain_filter::drop 中 DropGuard 的作用是什么?

为什么在 macOS / iOS 上切换 WiFi 网络时 reqwest 响应会挂起?

预期的整数,找到 `&{integer}`

只有一个字符被读入作为词法分析器的输入

为实现特征的所有类型实现显示

有没有办法隐藏类型定义?