当定义了从T到U的From转换时,将Idiomatic Option<T>转换为Option<U>。

12
给定两个任意大小的类型T和U,其中U: From,标准库为什么没有提供From> for Option的原因是什么?我尝试过这样做,但是得到了冲突的实现错误,所以显然存在限制,只是不确定具体在哪里。是的,我知道可以使用Option::map()来实现,但是似乎标准库应该直接提供这个功能。
enum Opt<T> {
    Some(T),
    None,
}

impl<T: From<U>, U> From<Opt<T>> for Opt<U> {
    fn from(opt: Opt<T>) -> Self {
        match opt {
            Opt::Some(t) => Opt::Some(t.into()),
            Opt::None => Opt::None,
        }
    }
}

struct A;
struct B;

impl From<A> for B {
    fn from(_: A) -> Self {
        B
    }
}

fn main() {
    let a = Opt::Some(A);
    let _b: Opt<B> = a.into();
}

错误
error[E0119]: conflicting implementations of trait `From<Opt<_>>` for type `Opt<_>`
 --> src/bin/main.rs:6:1
  |
6 | impl<T: From<U>, U> From<Opt<T>> for Opt<U> {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: conflicting implementation in crate `core`:
          - impl<T> From<T> for T;

通常进行这种转换的方法要么是a.map(A::Into),要么是a.map(B::From)。(问题暗示使用map();只是为了方便未来的访问者,我想更明确地表达一下。) - undefined
1个回答

17
是的,有一个原因,因为它与impl<T> From<T> for T冲突,正如你在T == U的情况下注意到的那样。就像你不能编写这个impl一样,std也不能(即使当前的特化也不支持这个,而且特化不用于公共接口)。对于这样的impl(以及其他类型的类似impl),确实存在这样的愿望,只是不清楚如何实现。

谢谢Chayim,你知道有关编译器如何支持这种情况的相关讨论或RFC吗?此外,我听说过专门化的努力,但不确定为什么在这种情况下不适用? - undefined
@YuriAstrakhan 我认为从来没有提出过一个具体想法的RFC。更像是在https://internals.rust-lang.org/论坛上有一些想法在流传。至于特化,目前只能在impl严格更特化的情况下进行特化,也就是说,一个impl是另一个impl的严格子集,而不是在冲突实现的一般情况下。 - undefined
我要搜索什么才能找到关于这种专业的讨论?有没有一个非常专业的专业名称? :) - undefined
@YuriAstrakhan 我不认为有任何特殊的名称。讨论主要集中在IRLO上。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接