如何实施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 &lt;u8&gt;的装饰? 的全部内容, 来源链接: utcz.com/qa/266904.html

回到顶部