如何解构 &str 的向量?

hea*_*low 2 rust

我的情况:

let mut str_vect = Vec::new();
str_vect.push("a");
str_vect.push("b");
str_vect.push("c");
let [a, bc @ ..] = str_vect[..];
println!("{:?} {:?}", a, bc);
Run Code Online (Sandbox Code Playgroud)

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8e4c47b024e0c871676626069ec07d52

我收到此错误:

[&str]编译时无法知道type 值的大小

这是为什么?我可以以某种方式解构Vecof&str吗?

Cha*_*man 6

只需添加一个&:v[..]是 DST([T],不是 &[T])。只要我们只访问单个元素,这就没问题,但对于..生成切片的其余模式 ( ) - 它们也必须生成[T],而且是未调整大小的。&[T]另一方面,如果您匹配,则其余模式也会给出&[T](另一种可能性是使用ref- ref bc @ ..,但我不建议这样做)。

let [a, bc @ ..] = &str_vect[..];
Run Code Online (Sandbox Code Playgroud)

游乐场

但是,这会失败:

error[E0005]: refutable pattern in local binding: `&[]` not covered
 --> src/main.rs:6:8
  |
6 |    let [a, bc @ ..] = &str_vect[..];
  |        ^^^^^^^^^^^^ pattern `&[]` not covered
  |
  = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
  = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
  = note: the matched value is of type `&[&str]`
help: you might want to use `if let` to ignore the variant that isn't matched
  |
6 |    let (a, bc) = if let [a, bc @ ..] = &str_vect[..] { (a, bc) } else { todo!() };
  |    ++++++++++++++++                                  ++++++++++++++++++++++++++++
Run Code Online (Sandbox Code Playgroud)

这是因为除此之外的任何切片模式[..]都是可反驳的——也就是说,可能会失败。如果str_vect(理论上)有零个元素怎么办?在这种情况下我们无法绑定第一个元素!您需要if letmatch处理该案子。


pro*_*-fh 5

另一种解决方案,绝对不是解构,但在我看来更容易阅读,因为名称表达了意图,它将依赖于split_first().

    let (a, bc) = str_vect.split_first().unwrap();
Run Code Online (Sandbox Code Playgroud)

当然,应该考虑一些适当的错误处理而不是解包。

是的,另一个答案要好得多,因为它详细解释了所报告错误的起源(我刚刚投票了;^)。