如何实施Vec <u8>的装饰?
Rust为字符串提供了修剪方法:str.trim()删除前导和尾随空白。我想要一个方法对于字节串也是一样的。它应该采取Vec<u8>
并删除前导和尾随空格(空格,0x20和htab,0x09)。如何实施Vec <u8>的装饰?
写trim_left()
很容易,你可以用与skip_while()
迭代器:Rust Playground
fn main() { let a: &[u8] = b" fo o ";
let b: Vec<u8> = a.iter().map(|x| x.clone()).skip_while(|x| x == &0x20 || x == &0x09).collect();
println!("{:?}", b);
}
但修剪我需要向前看,如果没有其他的字母列表中的空白是经过正确的字符找到。
回答:
这里有一个返回切片,而不是一个新的Vec<u8>
,作为str::trim()
做的实现。它也在[u8]
上实现,因为这比Vec<u8>
更普遍(你可以便宜地从矢量中获取片,但是从片创建矢量的成本更高,因为它涉及堆分配和副本)。
trait SliceExt { fn trim(&self) -> &Self;
}
impl SliceExt for [u8] {
fn trim(&self) -> &[u8] {
fn is_whitespace(c: &u8) -> bool {
*c == b'\t' || *c == b' '
}
fn is_not_whitespace(c: &u8) -> bool {
!is_whitespace(c)
}
if let Some(first) = self.iter().position(is_not_whitespace) {
if let Some(last) = self.iter().rposition(is_not_whitespace) {
&self[first..last + 1]
} else {
unreachable!();
}
} else {
&[]
}
}
}
fn main() {
let a = b" fo o ";
let b = a.trim();
println!("{:?}", b);
}
如果你真的需要一个Vec<u8>
的trim()
后,你可以调用into()
片上把它变成一个Vec<u8>
。
fn main() { let a = b" fo o ";
let b: Vec<u8> = a.trim().into();
println!("{:?}", b);
}
回答:
我们所要做的就是找到第一个非空白字符的索引,一次从开始向前计数,另一次从结束向后计数。
fn is_not_whitespace(e: &u8) -> bool { *e != 0x20 && *e != 0x09
}
fn main() {
let a: &[u8] = b" fo o ";
// find the index of first non-whitespace char
let begin = a.iter()
.position(is_not_whitespace);
// find the index of the last non-whitespace char
let end = a.iter()
.rev()
.position(is_not_whitespace)
.map(|j| a.len() - j);
// build it
let vec = begin.and_then(|i| end.map(|j| a[i..j].iter().collect()))
.unwrap_or(Vec::new());
println!("{:?}", vec);
}
以上是 如何实施Vec <u8>的装饰? 的全部内容, 来源链接: utcz.com/qa/266904.html