在 Rust 中使用 Some 内的选项进行字符串匹配

4

问题描述

我正在尝试使用匹配语句来匹配选项字符串。

let option_string = Some(String::from("Bob"));
    
match option_string {
  Some("Mike") => false,
  Some("Bob") => true,
  _ => false,
}

很明显,出现了错误expected struct 'String, found '&str'

我尝试将其转换为字符串

Some("Mike".to_string()) => false

// Or
Some(String::from("Mike")) => false

但面对另一个错误:'fn'调用在模式中是不允许的


唯一有效的方法是在Some之前将Mike放入变量中。

let mike = String::from("Mike");

// and in match
Some(mike) => true,

问题

有没有更加优雅的方式来匹配match语句中的String而不是字符串字面值,并且还包含Option值?

我找到了一个答案,但它看起来并不够优雅。除了创建额外的变量或函数之外,是否只有这一种可能的方法?


也许可以使用option_string.as_deref() - Brian61354270
顺便提一下,在这个虚构的例子中,表达式 option_string.as_deref() == Some("Bob") 优于 match - cdhowie
@cdhowie 我相信这只是一个简化的例子,以便更好地阐述问题。 - Finomnis
1
@Finomnis 对于从网络搜索到这里的人来说,仍然值得指出。 - cdhowie
1个回答

6
let mike = String::from("Mike");

// and in match
Some(mike) => true,

这是一个误解,很抱歉。在match表达式的左侧不允许使用变量。将名称放在左侧实际上会创建一个包含匹配内容的新变量。因此,在您的match子句中,变量mike匹配所有内容,然后携带匹配的String;它不是与外部变量mike相同的变量。
请注意此代码示例:
fn main() {
    let option_string = Some(String::from("Bob"));

    // Note how this line gets the compiler warning "unused variable".
    // You could leave this line out completely and it would still
    // compile.
    let mike = String::from("Mike");

    let result = match option_string {
        Some(mike) => {
            println!("Matched 'Mike': {}", mike);
            true
        }
        _ => false,
    };

    println!("{:?}", result);
}

Matched 'Mike': Bob
true

一般而言,您只能与编译时常量进行匹配。如果您想要比较两个变量,则必须使用if


解决方案

话虽如此,您的第一个示例很容易修复:

fn main() {
    let option_string = Some(String::from("Bob"));

    let result = match option_string.as_deref() {
        Some("Mike") => false,
        Some("Bob") => true,
        _ => false,
    };

    println!("{:?}", result);
}

true

请注意 .as_deref(),它从 Option<String> 借用一个 Option<&str>,使其与字符串字面量匹配表达式兼容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接