如何从返回 impl Trait 的函数初始化通用结构体的字段?

问题描述 投票:0回答:1

我有一个带有泛型类型字段的结构体和一个返回

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 中表达?

generics rust traits
1个回答
1
投票

您缺少的是

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();
}
© www.soinside.com 2019 - 2024. All rights reserved.