Dados dois tipos de tamanho arbitrário T
e U
, onde U: From<T>
, há uma razão pela qual a biblioteca padrão não fornece From<Option<T>> for Option<U>
um where U: From<T>
? Tentei fazer isso, mas recebi um erro de implementação conflitante, então claramente há uma limitação, mas não tenho certeza de onde. E sim, eu entendo que posso fazer isso com um Option::map()
, mas parece que o std deveria fornecer isso imediatamente.
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();
}
Erro
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;
Sim, há um motivo, porque entra em conflito com o
impl<T> From<T> for T
que você notou no caseT == U
. Assim como você não pode escrever este impl, o std também não pode (mesmo a especialização atual não suporta isso e a especialização não é usada para interfaces públicas). Há um desejo por tal impl (e impls semelhantes para outros tipos), mas não está claro como fazê-lo.