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]);
}
答案 0 :(得分:4)
如果您只需要使用第一部分或第二部分,也可以避免不必要的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)
}
然后,如果您确实需要Vec
,则可以在结果上进行映射:
split(&[1u8, 2u8, 3u8], &[2u8]).map(|s| s.to_vec())
当然,如果您愿意,可以将to_vec()
转换为功能:
second.or(first).map(|s| s.to_vec())
我在迭代器上调用fuse()
,以保证在返回第一个None
后它总是返回None
(一般迭代器无法保证)协议)。
答案 1 :(得分:1)
您可以做的一件事是collect
新拥有的Vec
中拆分的结果,如下所示:
fn split(slice: &[u8], splitter: &[u8]) -> Option<Vec<u8>> {
let parts: Vec<&[u8]> = slice.split(|b| splitter.contains(b)).collect();
let len = parts.len();
if len >= 2 {
Some(parts.iter().nth(1).unwrap().to_vec())
} else if len >= 1 {
Some(parts.iter().nth(0).unwrap().to_vec())
} else {
None
}
}
答案 2 :(得分:1)
其他答案是回答问题的好建议,但我想指出另一个通用解决方案:创建多个迭代器:
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]);
}
通常可以创建多个只读迭代器。有些迭代器甚至实现Clone
,所以你可以说iter.clone().count()
。不幸的是,Split
不是其中之一,因为它拥有传入的闭包。