将切片模式与字符串切片一起使用

Using slice patterns with a slice of Strings

我正在尝试在 String 的切片上使用切片模式。这不起作用,因为 Rust 不匹配切片的 Strings 与 &str 文字。我找不到如何将 Strings 的切片转换为 &strs 的切片。

#![feature(slice_patterns)]

fn main() {
    // A slice of strings.
    let x = ["foo".to_owned(), "bar".to_owned()];
    match x {
        ["foo", y] => println!("y is {}.", y),
        _ => println!("I did not expect this."),
    }
}

Playground

从技术上讲,您没有 Strings (&[String]) 的切片,您有 array Strings ([String; 2]).

我们来看一个小案例:

fn main() {
    match "foo".to_owned() {
        "foo" => println!("matched"),
        _ => unreachable!(),
    }
}

在这里,我们得到相同的错误信息:

error[E0308]: mismatched types
 --> src/main.rs:3:9
  |
3 |         "foo" => println!("matched"),
  |         ^^^^^ expected struct `std::string::String`, found reference
  |
  = note: expected type `std::string::String`
             found type `&'static str`

这种情况下的解决方法是将 String 更改为 &str,这是切片模式所理解的:

let s = "foo".to_owned();
match s.as_str() {
    "foo" => println!("matched"),
    _ => unreachable!(),
}

另请参阅:

  • How to match a String against string literals in Rust?

那么,我们如何将其扩展到您的示例?直接的事情就是做同样的事情两次:

fn main() {
    let x = ["foo".to_owned(), "bar".to_owned()];

    match [x[0].as_str(), x[1].as_str()] {
        ["foo", y] => println!("y is {}.", y),
        _ => unreachable!(),
    }
}

但是,这不适用于切片 (&[T]) 的情况,因为我们只处理两个值,而不是任意数量。在那种情况下,我们需要做一个临时的 Vec:


fn main() {
    let x = ["foo".to_owned(), "bar".to_owned()];
    let x2: Vec<_> = x.iter().map(|x| x.as_str()).collect();

    match x2.as_slice() {
        ["foo", y] => println!("y is {}.", y),
        _ => unreachable!(),
    }
}

请注意,您必须将 Vec 转换为切片本身 (x2.as_slice()),因为切片模式只能理解切片。