Providing an implementation when both trait and type are not in this crate [duplicate]

二次信任 提交于 2019-12-04 01:18:57

问题


I want to provide an implementation of a trait ToHex (not defined by me, from serialize) for a primitive type u8:

impl ToHex for u8 {
    fn to_hex(&self) -> String {
        self.to_str_radix(16)
    }
}

The problem is I get this compiler error:

error: cannot provide an extension implementation where both trait and type are not defined in this crate

I understand the reason of this error and its logic, this is because both the trait and the primitive type are external to my code. But how can I handle this situation and provide an ToHex implementation for u8? And more generally how do you handle this kind of issue, it seems to me that this problem must be common and it should be possible and easy to extend types like this?


回答1:


You should use a newtype struct to do this:

pub struct U8(pub u8)

impl ToHex for U8 {
    fn to_hex(&self) -> String {
        let U8(x) = *self;
        x.to_str_radix(16)
    }
}

This does mean, however, that you should wrap u8 into U8 where you need to perform this conversion:

let x: u8 = 127u8

// println!("{}", x.to_hex());   // does not compile
println!("{}", U8(x).to_hex());

This is absolutely free in terms of performance.




回答2:


I realize this is almost a year old, but the answer was never accepted and I think I've found an alternate solution, that I thought would be good to document here.

In order to extend the functionality of the u8 through traits, instead of trying to extend ToHex, why not create a new trait?

trait MyToHex {
    fn to_hex(&self) -> String;
}

impl MyToHex for u8 {
    fn to_hex(&self) -> String {
        format!("{:x}", *self)
    }
}

then used like so

fn main() {
    println!("{}", (16).to_hex());
}

This has the advantage that you don't have to wrap every u8 variable with a new and superfluous data type.

The disadvantage is that you still can't use a u8 in a external function (i.e std library, or one you have no control over) that requires the ToHex trait (Vladimir Matveev's solution works in this case), but from OP it sounds like all you want to do is extend u8 only inside your code.



来源:https://stackoverflow.com/questions/24340712/providing-an-implementation-when-both-trait-and-type-are-not-in-this-crate

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!