parts.count()导致所有权转移,因此parts不能再使用.
fn split(slice: &[u8], splitter: &[u8]) -> Option<Vec<u8>> {
let mut parts = slice.split(|b| splitter.contains(b));
let len = parts.count(); //ownership transfer
if len >= 2 {
Some(parts.nth(1).unwrap().to_vec())
} else if len >= 1 {
Some(parts.nth(0).unwrap().to_vec())
} else {
None
}
}
fn main() {
split(&[1u8, 2u8, 3u8], &[2u8]);
}
Run Code Online (Sandbox Code Playgroud)
Vec如果您只需要使用第一或第二部分,也可以避免不必要的分配:
fn split<'a>(slice: &'a [u8], splitter: &[u8]) -> Option<&'a [u8]> {
let mut parts = slice.split(|b| splitter.contains(b)).fuse();
let first = parts.next();
let second = parts.next();
second.or(first)
}
Run Code Online (Sandbox Code Playgroud)
然后,如果您确实需要一个Vec,则可以映射结果:
split(&[1u8, 2u8, 3u8], &[2u8]).map(|s| s.to_vec())
Run Code Online (Sandbox Code Playgroud)
当然,如果你愿意,你可以将to_vec()转换移动到函数中:
second.or(first).map(|s| s.to_vec())
Run Code Online (Sandbox Code Playgroud)
我调用fuse()迭代器是为了保证它None在第一个返回后总是None返回(一般迭代器协议不保证)。
其他答案是回答您的问题的好建议,但我想指出另一个通用解决方案:创建多个迭代器:
fn split(slice: &[u8], splitter: &[u8]) -> Option<Vec<u8>> {
let mut parts = slice.split(|b| splitter.contains(b));
let parts2 = slice.split(|b| splitter.contains(b));
let len = parts2.count();
if len >= 2 {
Some(parts.nth(1).unwrap().to_vec())
} else if len >= 1 {
Some(parts.nth(0).unwrap().to_vec())
} else {
None
}
}
fn main() {
split(&[1u8, 2u8, 3u8], &[2u8]);
}
Run Code Online (Sandbox Code Playgroud)
您通常可以创建多个只读迭代器。有些迭代器甚至实现了Clone,所以你可以直接说iter.clone().count()。不幸的是,Split它不是其中之一,因为它拥有传入的闭包。
| 归档时间: |
|
| 查看次数: |
3247 次 |
| 最近记录: |