Rust中的匹配字符串

Nat*_*han 4 string matching rust

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

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

相关的错误是:

10 |         "foo" => {                                                                                 
   |         ^^^^^ expected struct `std::string::String`, found reference
Run Code Online (Sandbox Code Playgroud)

发生此错误后,我决定将代码更改为:

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

    match s {
        String::from("foo") => {
            println!("Yes");
        }
        _ => {
            println!("No");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,我希望拥有正确的类型,但事实并非如此:

10 |         String::from("foo") => {                                                                   
   |         ^^^^^^^^^^^^^^^^^^^ not a tuple variant or struct
Run Code Online (Sandbox Code Playgroud)

我对编译器发出的消息感到非常困惑,最后我设法通过实现使其起作用:

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

    match &s as &str {
        "foo" => {
            println!("Yes");
        }
        _ => {
            println!("No");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我不了解使该解决方案成为正确解决方案的基本机制,以及为什么我的第二个示例不起作用。

Mat*_*247 5

第一个示例不起作用,因为s它的类型为String,这是一个字符串变体,在其中拥有数据。它与字符串文字(可以用作type &str)匹配。match不了解如何比较这两种不同的类型,因此会出错。

但是,通过实现实现对的String取消引用,这意味着可以在需要a的地方使用对的引用,例如将其与a 进行比较。这就是第三个示例中发生的情况。通过创建引用,隐式解引用可能发生,并且这两种类型变得可比。&strDeref<Target=str>String&str&s

通过使用创建&strfrom 的显式方法,您可以用更少的魔术来实现同一件事String

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

    match s.as_str() {
        "foo" => {
            println!("Yes");
         },
         _ => {
             println!("No");
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

第二个示例试图使事物具有可比性,String用通用类型代替&str。这是行不通的,因为match需要在左侧使用模式,而不能创建新的结构(也要在后台分配)的函数调用。即使它可以工作(例如,通过将String创建内容移出比赛之外),也不太理想,因为新String方法需要分配内存。