从泛型内部类型派生所有转换运算符

Derive all convertion operators from generic inner type

提问人:Dekakaruk 提问时间:9/26/2023 最后编辑:cafce25Dekakaruk 更新时间:9/28/2023 访问量:65

问:

我正在尝试使用新类型模式,但我希望它只有语义意义,而不强制表示。所以让我们说

struct Amount<T>(T);

所以以后我可以使用 or – 两者都在语义上有效,内部类型将仅取决于上下文。但现在我想从内部类型继承所有转换运算符:Amount<i32>Amount<f64>

impl<T, U: From<T>> TryFrom<Amount<T>> for Amount<U> {
    type Error = U::Error;

    fn try_from(v: Amount<T>) -> Self {
        v.0.try_into().map(Self)
    }
}

由于与 的实现冲突,它不会编译。如何绕过此限制?impl<T, U> TryFrom<U> for T where U: Into<T>;

泛型 Rust 元编程 包装器

评论

1赞 PitaJ 9/26/2023
不幸的是,没有办法绕过限制。唯一的其他选择是针对您实际想要涵盖的每种类型手动实现。
0赞 Chayim Friedman 9/26/2023
您可以使用方法而不是特征实现来做到这一点。
0赞 Aleksander Krauze 9/26/2023
如果你问是否有可能“自动”实现所有实现的特征,并将它们转发到内部价值,答案是这是不可能的(我认为永远不可能)。你必须手动(或使用一些宏)实现你感兴趣的特征(这非常困难,当你是一个库作者并希望与更大的 rust 生态系统集成时,你经常会看到这些东西被功能门保护,例如 for 或 )。Amount<T>Tserdenum
0赞 Dekakaruk 9/26/2023
@AleksanderKrauze我只需要一组有限的标准特征,其中似乎是最突出和最困难的From

答:

0赞 Max Meijer 9/28/2023 #1

您无法绕过该限制(尽管有一个不稳定的专业化实现建议,我不确定它在这种情况下是否有效)。但是:你也不需要绕过它。

您可以只实现 的特征,然后在 的实现中简单地使用它。然后,因为会有一个开箱即用的实现。Into<T>Amount<T>TryFrom<U>U : Into<T>Amount<T> : Into<T>TryFrom<Amount<T>>

impl<T> Into<T> for Amount<T> {
    type Error = U::Error;

    fn into(v: Amount<T>) -> T {
        v.0
    }
}
impl<T, U : Into<T>> TryFrom<U> for Amount<T> {
    type Error = U::Error;

    fn from(v: U) -> Self {
        v.into().map(Self)
    }
}