You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对bytes crate中的BytesMut执行trim操作?

给BytesMut实现trim字节的方法

因为bytes crate的BytesMut本身没有内置的trim方法,我们可以通过扩展trait来实现这个功能,下面分两种场景给出实现:

1. Trim ASCII空白字符(对应你的示例场景)

这个实现会移除字节序列前后的ASCII空白字符(包括空格、制表符、换行符等),和Rust标准库的str::trim()行为一致:

use bytes::BytesMut;

// 定义扩展trait,给BytesMut添加trim方法
trait BytesMutTrimExt {
    // 原地修改原BytesMut,返回自身引用
    fn trim_ascii_whitespace(&mut self) -> &mut Self;
    // 返回新的trim后的BytesMut,不修改原实例
    fn trimmed_ascii_whitespace(&self) -> BytesMut;
}

impl BytesMutTrimExt for BytesMut {
    fn trim_ascii_whitespace(&mut self) -> &mut Self {
        let slice = self.as_slice();
        
        // 找到第一个非空白字节的位置,全空白则取0
        let start = slice.iter().position(|&b| !b.is_ascii_whitespace()).unwrap_or(0);
        // 找到最后一个非空白字节的位置+1,全空白则取0
        let end = slice.iter().rposition(|&b| !b.is_ascii_whitespace()).map_or(0, |pos| pos + 1);

        // 跳过前面的空白字节
        if start > 0 {
            self.advance(start);
        }
        // 截断后面的空白字节
        if end < self.len() {
            let _ = self.split_off(end - start);
        }
        
        self
    }

    fn trimmed_ascii_whitespace(&self) -> BytesMut {
        let slice = self.as_slice();
        
        let start = slice.iter().position(|&b| !b.is_ascii_whitespace()).unwrap_or(0);
        let end = slice.iter().rposition(|&b| !b.is_ascii_whitespace()).map_or(0, |pos| pos + 1);
        
        // 截取子切片并转为BytesMut
        self.slice(start..end).into()
    }
}

使用示例

完全匹配你的需求场景:

fn main() {
    // 方式1:原地修改原实例
    let mut some_bytes = BytesMut::from("  hello world  ");
    some_bytes.trim_ascii_whitespace();
    assert_eq!(some_bytes, BytesMut::from("hello world"));

    // 方式2:返回新实例,不改动原数据
    let some_bytes = BytesMut::from("  hello world  ");
    let trim_bytes = some_bytes.trimmed_ascii_whitespace();
    assert_eq!(trim_bytes, BytesMut::from("hello world"));
}

2. Trim指定的单个字节

如果需要移除前后特定的字节(比如移除前后的x或0),可以实现通用的trim指定字节方法:

use bytes::BytesMut;

trait BytesMutTrimExt {
    // 原地trim指定字节
    fn trim(&mut self, byte: u8) -> &mut Self;
    // 返回新的trim指定字节后的BytesMut
    fn trimmed(&self, byte: u8) -> BytesMut;
}

impl BytesMutTrimExt for BytesMut {
    fn trim(&mut self, byte: u8) -> &mut Self {
        let slice = self.as_slice();
        
        let start = slice.iter().position(|&b| b != byte).unwrap_or(0);
        let end = slice.iter().rposition(|&b| b != byte).map_or(0, |pos| pos + 1);

        if start > 0 {
            self.advance(start);
        }
        if end < self.len() {
            let _ = self.split_off(end - start);
        }
        
        self
    }

    fn trimmed(&self, byte: u8) -> BytesMut {
        let slice = self.as_slice();
        
        let start = slice.iter().position(|&b| b != byte).unwrap_or(0);
        let end = slice.iter().rposition(|&b| b != byte).map_or(0, |pos| pos + 1);
        
        self.slice(start..end).into()
    }
}

使用示例

fn main() {
    let mut some_bytes = BytesMut::from("xxhello worldxx");
    some_bytes.trim(b'x');
    assert_eq!(some_bytes, BytesMut::from("hello world"));
}

边界情况说明

  • 如果整个BytesMut都是空白/指定字节,trim后会得到空的BytesMut
  • 方法内部使用了BytesMut的原生方法(advance、split_off、slice),性能和原生操作一致

内容的提问来源于stack exchange,提问作者realzhujunhao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 22:27:22