我有一个带有泛型类型字段的结构体和一个返回
impl Trait
的函数。我需要用函数的结果初始化该字段,但编译器无法识别这些类型是兼容的(playground):
trait Trait {}
struct St {}
impl Trait for St {}
fn ret_impl() -> impl Trait {
St{}
}
//-------------------
struct Generic<T: Trait>
{
field: T,
}
impl<T: Trait> Generic<T> {
fn new() -> Generic<T> {
Generic{
field: ret_impl()
}
}
}
fn main () {
let var = Generic::new();
}
这给了我一个错误:
error[E0308]: mismatched types
--> src/main.rs:21:20
|
7 | fn ret_impl() -> impl Trait {
| ---------- the found opaque type
...
18 | impl<T: Trait> Generic<T> {
| - expected this type parameter
...
21 | field: ret_impl()
| ^^^^^^^^^^ expected type parameter `T`, found opaque type
|
= note: expected type parameter `T`
found opaque type `impl Trait`
= 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
For more information about this error, try `rustc --explain E0308`.
这让我感到困惑,因为编译知道 ret_impl() 返回实现 Trait 的内容,并且该字段可能包含实现 Trait 的内容。那么将一个分配给另一个会有什么问题呢?看来我错过了一些明显的东西。
是否有可能使其工作或者无法在 Rust 中表达?
您缺少的是
ret_impl
决定其返回类型是什么(St
),但是 Generic::new()
的 caller决定
T
是什么,并且可以是实现 Trait
的 any类型。当该类型不完全是
St
时,就会出现类型不匹配的情况。
let var = Generic::new();
也将无法编译,因为你没有告诉它 T
是什么,并且任何实现 Trait
的类型都会满足边界。
看来您可能希望
ret_impl
成为 Trait
的函数:
trait Trait {
fn ret_impl() -> Self;
}
struct St {}
impl Trait for St {
fn ret_impl() -> Self {
St {}
}
}
//-------------------
struct Generic<T: Trait> {
field: T,
}
impl<T: Trait> Generic<T> {
fn new() -> Generic<T> {
Generic { field: T::ret_impl() }
}
}
fn main() {
let var: Generic<St> = Generic::new();
}