简体   繁体   English

我如何惯用地实现 From <a<t> > 对于 A<u>没有冲突?</u> </a<t>

[英]How do I idiomatically implement From<A<T>> for A<U> without conflict?

I have created a generic, monadic type -- call it A<T> .我创建了一个通用的单子类型——称之为A<T> I would like to be able to have this type convert safely between A<T> to A<U> if U: From<T> , while still encapsulating it within an A<_> , ideally without having to expose or use a T directly.如果U: From<T> ,我希望能够在A<T>A<U>之间安全地转换这种类型,同时仍然将它封装在A<_>中,理想情况下不必公开或使用T直接地。

What I would like to do, is to implement From<A<T>> constrained with U: From<T> ;想做的是实现From<A<T>>U: From<T>约束; however the following code does not compile:但是以下代码无法编译:

struct A<T>{
    val: T
}

impl<T, U> From<A<T>> for A<U>
    where U: From<T>
{
    fn from(other: A<T>) -> A<U> {
        A{ val: U::from(other.val) }
    }
}

The above fails to compile due to the generic implementation impl<T> From<T> for T defined in core .由于在core中定义的 T 的通用实现impl<T> From<T> for T上述代码无法编译。 The full error is:完整的错误是:

 error[E0119]: conflicting implementations of trait `std::convert::From<A<_>>` for type `A<_>` --> src/lib.rs:5:1 | 5 | impl<T, U> From<A<T>> for A<U> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: conflicting implementation in crate `core`: - impl<T> From<T> for T;

Demo 演示

The reason for why this fails is clear: this definition applies for cases where T == U , which would make this impl From<A<T>> for A<T> which is the same as From<T> for T -- and thus, a conflict.失败的原因很明显:此定义适用于T == U的情况,这将使impl From<A<T>> for A<T>From<T> for T相同 -因此,冲突。 However what is not clear is what the idiomatic approach is to overcome this -- since I cannot imagine I am the only one to want to keep a type fully encapsulated.然而,尚不清楚克服这一问题的惯用方法是什么——因为我无法想象我是唯一一个想要完全封装类型的人。

Is this possible to achieve without needing unstable features like negative trait-bounds or trait-specializations?这是否有可能在不需要不稳定特征(如负面特征界限或特征专业化)的情况下实现? If not, what is the general, idiomatic approach to support a From conversion while still encapsulating the type?如果不是,那么在封装类型的同时支持From转换的一般惯用方法是什么? Am I stuck implementing a function that behaves exactly like fn from(...) , but without implementing the trait?我是否坚持实施一个 function ,其行为与fn from(...)完全一样,但没有实施该特征?

There is no way to make没有办法使

impl<T, U> From<A<T>> for A<U>
    where U: From<T>

succeed.成功。 (Even if a future version of Rust offers specialization, it would only work here if the built-in From<T> for T impl were marked as allowing specialization.) (即使 Rust 的未来版本提供专业化,它也只能在From<T> for T被标记为允许专业化的情况下才能在这里工作。)

Your choices are:您的选择是:

  • Implement the conversion for concrete non-equal types — From<A<Bar>> for A<Foo> .实现具体不等类型的转换—— From<A<Bar>> for A<Foo> (I assume this is not desirable for your application, but you seem interested in a broad answer.) (我认为这不适合您的应用程序,但您似乎对广泛的答案感兴趣。)

  • As you already thought of, “implementing a function that behaves exactly like fn from(...) , but without implementing the trait”.正如您已经想到的,“实现一个 function,它的行为与fn from(...)完全一样,但没有实现 trait”。 I'd write it like:我会这样写:

     impl<T> A<T> { fn convert<U>(self) -> A<U> where T: Into<U> { A { val: self.val.into() } } }

    But note that if your monadic type has a map() method, then this is just .map(Into::into) .但请注意,如果你的 monadic 类型有一个map()方法,那么这就是.map(Into::into)

  • Define your own conversion trait, that is not From .定义您自己的转换特征,而不是From

    There's probably no reason to do this in your case, unless you have other types similar to A , but considered broadly, this is actually fairly common;在您的情况下可能没有理由这样做,除非您有其他类似于A类型,但从广义上考虑,这实际上是相当普遍的; many libraries define IntoFoo trait(s), for various reasons.出于各种原因,许多库都定义IntoFoo特征。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从IQueryable进行投射 <T> 到IQueryable <U>和</u> <Func<T, bool> <U>&gt;至</u> <Func<U, bool> <U>&gt;好玩吗?</u> - How do I cast from IQueryable<T> to IQueryable<U> and <Func<T, bool>> to <Func<U, bool>> for fun? Rust 是否执行自<vec<t> &gt; 对于 Vec <u>,如果我已经实现 From</u><t> <u>为了你?</u> </t></vec<t> - Does Rust implement From<Vec<T>> for Vec<U> if I have already implemented From<T> for U? 如何将 `where T : U` 泛型类型参数约束从 C# 转换为 F#? - How do I translate a `where T : U` generic type parameter constraint from C# to F#? 我如何实现IComparable <T> ? - How do I implement IComparable<T>? 我如何实现IEnumerable <T> - How do I implement IEnumerable<T> 如何实现成为cpp文件的成员函数MyClass <T> :: MyMember <U>?</u> - how to implement into cpp file a member function MyClass<T>::MyMember<U>? 如何解释方法比较的参数(功能<!--? super T,? extends U-->密钥提取器)? - How do I interpret the argument of method comparing(Function<? super T,? extends U> keyExtractor)? 如何在类型T和U上声明泛型函数,不允许T和U的空交集 - How do you declare a function generic on types T and U that disallows an empty intersection of T and U 给定`T`和`U`,其中`T延伸U`如何返回&#39;U` - Given `T` and `U` where `T extends U` how to return a `U` 如何实现From将一种结果类型转换为另一种? - How do I implement From to convert one Result type to another?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM