【发布时间】:2022-12-13 12:12:38
【问题描述】:
假设我有一个实现 Debug 的类型的值,并且我想用 utf-16 对格式化该值的结果进行编码。一种方法是使用 format!,然后将 str 转换为 utf-16:
use std::fmt::Debug;
#[derive(Debug)]
pub struct User {
name: String,
some_ids: [u8; 16],
// more fields, etc. Quite a few of them, actually
}
pub fn display_to_u16(user: &User) -> Vec<u16> {
let asutf8 = format!("{user:#?}");
asutf8.encode_utf16().collect()
}
但是不直接将结果写为 utf-16 字符串似乎很浪费——或者更准确地说是 utf-16 代码点的向量。有什么方法可以直接将值格式化为 utf-16 字符串吗?
注意:真正的要求是使用抽象的dyn Debug类型作为tracing_subscriber::field::Visit::record_debug的实现的一部分。 User 类型应仅作为示例。 “简单地”实现不同的序列化方案是不可行的。使用 Debug 特征是问题的一个组成部分。
【问题讨论】:
-
我不确定你可以。转换开销应该非常小,除非它位于代码的真正热点内。
-
@tadman 这是在每个
tracing事件和跨度进入/退出时短暂分配几 kB。所以它并没有那么糟糕,但我想问一下如何避免额外的混乱以防万一,避免它肯定会受到赞赏。如果可能的话,未来对这个问题的一些 ping 可能只是提醒我改变它。 -
UTF-8 到 UTF-16 只是一些字节交换,所以应该不会太糟糕。不过,我认为 Rust 非常致力于在内部使用 UTF-8,因此我不希望能够在不进行转换的情况下直接写入 UTF-16。 UTF-16 输出是否绝对必要?它往往要大得多,这对于大量的跟踪输出来说可能是个问题。
-
@tadman 是的,支持 UTF-16。输出最终出现在 JS 领域(上下文是一个 wasm 应用程序),其中字符串被编码为 UTF-16。我想在 rust 方面进行这种转换,因为通过
TextDecoder而不是会涉及额外的ffi调用,这些调用成本更高(并且无论如何都在引擎盖下进行类似的转换)