鉴于以下特征和实施:
trait Wrapper<Type> {
type Inner : Wrapped<Type>;
fn bind<B, F>(self, f: F) -> <B as Wrapped<Type>>::Outer
where B: Wrapped<Type>, F: Fn(Self::Inner) -> <B as Wrapped<Type>>::Outer;
}
trait Wrapped<Type> {
type Outer : Wrapper<Type>;
}
struct Opt;
impl<T> Wrapped<Opt> for T {
type Outer = Option<T>;
}
impl<T> Wrapper<Opt> for Option<T> {
type Inner = T;
fn bind<B, F>(self, f: F) -> <B as Wrapped<Opt>>::Outer
where B: Wrapped<Opt>, F: Fn(Self::Inner) -> <B as Wrapped<Opt>>::Outer {
match self {
Some(a) => f(a),
None => None, // *** fails to compile
}
}
}
对于人类而言,<B as Wrapped<Opt>>::Outer
类型必须始终为Option<B>
,但rustc
无法理解这一点,这一点很明显:
src/main.rs:47:21: 47:25 error: mismatched types:
expected `<B as Wrapped<Opt>>::Outer`,
found `core::option::Option<_>`
(expected associated type,
found enum `core::option::Option`) [E0308]
src/main.rs:47 None => None,
^~~~
有没有办法说服它这是安全的?我甚至满足于unsafe
解决方案,但mem::transmute
也是不允许的,因为它不能证明类型大小相同且对齐(即使只涉及一个真实类型而不是甚至任何可能搞乱对齐的新型包装器。)
答案 0 :(得分:6)