首页 文章

当特征和类型都不在此包中时提供实现[重复]

提问于
浏览
6

这个问题在这里已有答案:

我想为原始类型 u8 提供特征 ToHex (我没有定义,从 serialize )的实现:

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

我理解这个错误的原因及其逻辑,这是因为特征和原始类型都在我的代码外部 . 但是我如何处理这种情况并为 u8 提供 ToHex 实现?更一般地说,你如何处理这类问题,在我看来,这个问题必须是常见的,它应该是可能的,并且很容易扩展这样的类型?

2 回答

  • 4

    您应该使用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());
    

    这在性能方面完全免费 .

  • 10

    我意识到这已经快一年了,但答案从未被接受过,我想我已经找到了一个替代解决方案,我认为在这里记录会很好 .

    为了扩展 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 变量 .

    缺点是你仍然不能在外部函数中使用 u8 (即std库,或者你无法控制的那个)需要 ToHex 特性(Vladimir Matveev的解决方案适用于这种情况),但是从OP看起来它听起来像你想要做的只是在你的代码中扩展 u8 .

相关问题