简体   繁体   中英

Why does't Rust match an empty array?

I'm trying to match on an array in Rust:

let s = "x,y,z";
let v: Vec<_> = s.split(',').collect();
let (x, y, z) = match &v[..] {
    [x, y, z] => (x,y,z),
    [] => return Err("empty"),
    _ => return Err("wrong length"),
};
Ok(v)

When passing "" as s , I would expect to receive an Err("empty") , but I receive Err("wrong length") instead. What am I doing wrong?

s . split ( sep ) s . split ( sep ) will always return at least one element: if the separator sep doesn't appear in the input string, it will just yield a single element that is the entire string. More generally, if the separator sep appears N times in the string s , the iterator will always yield N+1 elements.

So when you call "".split(',') , you will get an iterator of a single element "" because the separator appears 0 times.

Here are two different approaches you can use if you want to avoid this:

// filter any empty segments, for example:
//   "" => [] instead of [""]
//   "x,y" => ["x", "y"]
//   "x,,y" => ["x", "y"] instead of ["x", "", "y"]
let v: Vec<_> = s.split(',').filter(|item| !item.is_empty()).collect();
// return empty array if input is empty, otherwise return all segments (even if empty):
//   "" => [] instead of [""]
//   "x,y" => ["x", "y"]
//   "x,,y" => ["x", "", "y"]
let v: Vec<_> = if s.is_empty() {
    vec![]
} else {
    s.split(',').collect()
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM