使用切片模式和一片字符串

时间:2015-11-22 19:32:53

标签: pattern-matching rust borrow-checker

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

#![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

1 个答案:

答案 0 :(得分:2)

从技术上讲,你没有String&[String])的片段,你有String数组[String; 2] })。

让我们来看一个较小的案例:

#![feature(slice_patterns)]

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

在这里,我们收到相同的错误消息:

error: mismatched types:
 expected `collections::string::String`,
    found `&'static str`
(expected struct `collections::string::String`,
    found &-ptr) [E0308]
<anon>:5         "foo" => println!("matched"),
                 ^~~~~

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

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

那么,我们如何将此扩展到您的示例?直截了当的是两次做同样的事情:

#![feature(slice_patterns)]

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

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

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

#![feature(slice_patterns)]

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

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

请注意,您必须将Vec转换为切片本身(&x2[..]),因为slice_patterns功能只能理解这些功能。

所有这一切都有助于指出为什么这个功能尚未被认为足以在整个语言的整个生命周期中保持稳定。 ^ _ ^您可能希望添加阅读并参与relevant stabilization bug for slice_patterns