问题
I did something like this, which works:
let s = " \"".as_bytes();
let (space, quote) = (s[0], s[1]);
I wanted to do something like this
&[space, quote] = " \"".as_bytes();
But it gives me the error
slice pattern syntax is experimental (see issue #23121)
Is it possible to do something similar?
回答1:
As the error tells you, slice pattern syntax is experimental. This means either the semantics are not clear or the syntax might change in the future. As a result, you need a nightly version of the compiler and to explicitly request that feature:
#![feature(slice_patterns)]
fn main() {
match " \"".as_bytes() {
&[space, quote] => println!("space: {:?}, quote: {:?}", space, quote),
_ => println!("the slice lenght is not 2!"),
}
}
Also note that you can't just write &[space, quote] = whatever
anyway because there is a possibility that whatever
is not the right length. To make the pattern matching exhaustive, you need a _
case or a case with ..
. What you tried would give another error:
error[E0005]: refutable pattern in local binding: `&[]`, `&[_]` and `&[_, _, _, ..]` not covered
--> src/main.rs:4:9
|
4 | let &[space, quote] = " \"".as_bytes();
| ^^^^^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _, _, ..]` 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
help: you might want to use `if let` to ignore the variant that isn't matched
|
4 | if let &[space, quote] = " \"".as_bytes() { /* */ }
As of Rust 1.26 you can pattern match on an array instead of a slice. If you convert the slice to an array, you can then match on it:
use std::convert::TryInto;
fn main() {
let bytes = " \"".as_bytes();
let bytes: &[_; 2] = bytes.try_into().expect("Must have exactly two bytes");
let &[space, quote] = bytes;
println!("space: {:?}, quote: {:?}", space, quote);
}
来源:https://stackoverflow.com/questions/38545609/pattern-matching-on-slices