我想为基本类型ToHex
提供特征serialize
(我未定义,来自u8
)的实现:
impl ToHex for u8 {
fn to_hex(&self) -> String {
self.to_str_radix(16)
}
}
问题是我得到了这个编译错误:
error: cannot provide an extension implementation where both trait and type are not defined in this crate
我理解这个错误的原因及其逻辑,这是因为特征和原始类型都在我的代码外部。但是,我如何处理这种情况并为ToHex
提供u8
实施?更一般地说,你如何处理这类问题,在我看来,这个问题必须是常见的,并且应该可以轻松扩展这样的类型?
答案 0 :(得分:10)
您应该使用newtype结构来执行此操作:
pub struct U8(pub u8)
impl ToHex for U8 {
fn to_hex(&self) -> String {
let U8(x) = *self;
x.to_str_radix(16)
}
}
但这确实意味着您应该将u8
包装到需要执行此转换的U8
中:
let x: u8 = 127u8
// println!("{}", x.to_hex()); // does not compile
println!("{}", U8(x).to_hex());
这在性能方面完全免费。
答案 1 :(得分:4)
我意识到这已经差不多一年了,但答案从未被接受过,我想我已经找到了一个替代解决方案,我认为在这里记录会很好。
为了通过特征扩展 u8 的功能,而不是尝试扩展 ToHex ,为什么不创建新的特征呢?
trait MyToHex {
fn to_hex(&self) -> String;
}
impl MyToHex for u8 {
fn to_hex(&self) -> String {
format!("{:x}", *self)
}
}
然后像这样使用
fn main() {
println!("{}", (16).to_hex());
}
这样做的好处是,您不必使用新的多余数据类型包装每个 u8 变量。
缺点是您仍然无法在外部函数(即std库或无法控制的函数库)中使用 u8 ,这需要 ToHex trait(弗拉基米尔·马特维耶夫的解决方案适用于这种情况),但是从OP来看,你只想在你的代码中扩展 u8 。