我的情况:
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)
我收到此错误:
[&str]编译时无法知道type 值的大小
这是为什么?我可以以某种方式解构Vecof&str吗?
只需添加一个&: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 let或match处理该案子。
另一种解决方案,绝对不是解构,但在我看来更容易阅读,因为名称表达了意图,它将依赖于split_first().
let (a, bc) = str_vect.split_first().unwrap();
Run Code Online (Sandbox Code Playgroud)
当然,应该考虑一些适当的错误处理而不是解包。
是的,另一个答案要好得多,因为它详细解释了所报告错误的起源(我刚刚投票了;^)。
| 归档时间: |
|
| 查看次数: |
767 次 |
| 最近记录: |