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

如何将实现Debug trait的值直接格式化为UTF-16字符串?

直接将实现Debug trait的值格式化为UTF-16向量

我需要将一个实现了Debug trait的值的格式化结果编码为UTF-16码点的向量。目前的做法是先用format!宏生成UTF-8字符串,再转换为UTF-16:

use std::fmt::Debug;

#[derive(Debug)]
pub struct User {
    name: String,
    some_ids: [u8; 16],
    // 更多字段...
}

pub fn display_to_u16(user: &User) -> Vec<u16> {
    let asutf8 = format!("{user:#?}");
    asutf8.encode_utf16().collect()
}

但这种先转UTF-8再转UTF-16的方式存在不必要的内存开销,有没有办法直接将值格式化为UTF-16向量?

补充说明:实际场景是在实现tracing_subscriber::field::Visit::record_debug时处理抽象的dyn Debug类型,User仅作为示例。必须基于Debug trait实现,无法更换序列化方案。


解决方案:自定义Write实现流式UTF-16编码

Rust的Debug格式化是通过Write trait完成的,我们可以实现一个自定义的Write结构体,直接将输入的UTF-8字符编码为UTF-16并写入向量,跳过中间的完整UTF-8字符串分配:

use std::fmt::{self, Debug};
use std::io::Write;

#[derive(Debug)]
pub struct User {
    name: String,
    some_ids: [u8; 16],
    // 其他字段...
}

// 自定义Writer,内部持有UTF-16码点向量
struct Utf16Writer(Vec<u16>);

impl Write for Utf16Writer {
    // 处理UTF-8字符串片段,直接编码为UTF-16并追加到向量
    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.0.extend(s.encode_utf16());
        Ok(())
    }

    // 优化单个字符的写入逻辑
    fn write_char(&mut self, c: char) -> fmt::Result {
        self.0.extend(c.encode_utf16());
        Ok(())
    }
}

// 通用方法:将任意Debug值格式化为UTF-16向量
pub fn debug_to_u16<T: Debug>(value: &T) -> Vec<u16> {
    let mut writer = Utf16Writer(Vec::new());
    // 直接调用Debug的格式化逻辑写入自定义Writer
    write!(writer, "{:#?}", value).expect("Debug格式化不会产生IO错误");
    writer.0
}

// 针对dyn Debug的使用示例
pub fn handle_dyn_debug(value: &dyn Debug) -> Vec<u16> {
    debug_to_u16(value)
}

方案优势

  • 避免了中间UTF-8字符串的内存分配和拷贝,流式处理格式化输出,内存占用更高效,尤其适合大体积的Debug输出场景。
  • 完全基于Debug trait实现,符合需求中的约束,同时支持具体类型和dyn Debug抽象类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:05:20