使用 Result::map 和 Box 时无法推断类型
为什么不能编译?
trait T {}
fn f<U: 'static + T, V, E>(f2: V) -> impl Fn() -> Result<Box<dyn T>, E>
where
V: Fn() -> Result<U, E>,
{
move || -> Result<Box<dyn T>, E> { f2().map(Box::new) }
}
错误信息是:
error[E0308]: mismatched types
--> src/lib.rs:7:40
|
7 | move || -> Result<Box<dyn T>, E> { f2().map(Box::new) }
| ^^^^^^^^^^^^^^^^^^ expected trait T, found type parameter
|
= note: expected type `std::result::Result<std::boxed::Box<(dyn T + 'static)>, _>`
found type `std::result::Result<std::boxed::Box<U>, _>`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
这个版本没问题:
trait T {}
fn f<U: 'static + T, V, E>(f2: V) -> impl Fn() -> Result<Box<dyn T>, E>
where
V: Fn() -> Result<U, E>,
{
move || -> Result<Box<dyn T>, E> {
match f2() {
Ok(result) => Ok(Box::new(result)),
Err(e) => Err(e),
}
}
}
在我看来,(dyn T + 'static)
和 U
是一样的;我说的对吗?
In my opinion, (dyn T + 'static)
and U
are the same; am I right?
我正在使用 rustc 1.39.0-nightly (f0b58fcf0 2019-09-11)
.
这是一个限制,我不知道它是否会在某一天编译.原因是 Rust 不知道在两种 Result
类型之间进行转换,(dyn T + 'static)
和 U
是完全不同的事物.如果这可以接受,您可以执行 f2().map(|x| Box::new(x) as _)
.
It's a limitation and I don't know if it will compile one day. The reason is that Rust doesn't know to convert between the two Result
types, (dyn T + 'static)
and U
are totally different things. If this acceptable you can do f2().map(|x| Box::new(x) as _)
.
强制转换将允许编译器将 U
转换为 (dyn T + 'static)
在将它放入结果之前,我们不需要显式转换输入编译器 inference会为我们做(在大多数情况下).
The cast will allow the compiler to transform U
into (dyn T + 'static)
before put it in the result, we don't need to explicit the cast type the compiler inference will do it for us (on most case).
一个 trait 对象可以从一个指向具体类型的指针获得,该类型通过强制转换来实现该 trait(例如 &x as &Foo)
A trait object can be obtained from a pointer to a concrete type that implements the trait by casting it (e.g. &x as &Foo)
参见动态调度 书的部分(在新书中没有找到任何信息).
See dynamic dispatch section of the book (didn't find any information in the new book).