Generics 我如何构造实现某个特性的许多潜在结构中的任何一个?

Generics 我如何构造实现某个特性的许多潜在结构中的任何一个?,generics,rust,traits,Generics,Rust,Traits,我在下面创建了一个小的生锈问题工作示例: trait TraitFoo { fn foo(&self) -> i32; } struct StructBar { var: i32, } impl TraitFoo for StructBar { fn foo(&self) -> i32 { self.var } } impl StructBar { fn new() -> StructBar {

我在下面创建了一个小的生锈问题工作示例:

trait TraitFoo {
    fn foo(&self) -> i32;
}

struct StructBar {
    var: i32,
}

impl TraitFoo for StructBar {
    fn foo(&self) -> i32 {
        self.var
    }
}

impl StructBar {
    fn new() -> StructBar {
        StructBar { var: 5 }
    }
}

struct FooHolder<T: TraitFoo> {
    myfoo: T,
}

impl<T: TraitFoo> FooHolder<T> {
    fn new() -> FooHolder<T> {
        FooHolder { myfoo: StructBar::new() }
    }
}

fn main() {
    let aaa = FooHolder::new();
}
TraitFoo特征{
fn foo(&self)->i32;
}
结构条{
var:i32,
}
StructBar的impl-TraitFoo{
fn foo(&self)->i32{
self.var
}
}
impl StructBar{
fn new()->StructBar{
StructBar{var:5}
}
}
结构FooHolder{
myfoo:T,
}
impl FooHolder{
fn new()->FooHolder{
FooHolder{myfoo:StructBar::new()}
}
}
fn main(){
设aaa=FooHolder::new();
}
无法通过以下方式编译:

错误[E0308]:类型不匹配
-->src/main.rs:27:9
|
27 | FooHolder{myfoo:StructBar::new()}
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^所需的类型参数,已找到struct`StructBar`
|
=注意:应为'FooHolder'类型`
找到类型“FooHolder”`
我希望能够从
FooHolder::new()
方法返回实现
TraitFoo
的任何可能的结构。我希望它将any
T:TraitFoo
作为返回类型,而不是本例中的
StructBar


我尝试过几种方法,但将
new()
移到trait中对我没有帮助,因为实现
TraitBar
的新结构可能会将不同的参数移到
new()

中。您似乎几乎走上了正确的轨道。让我们讨论一下要点:

函数
fn new()->FooHolder
的实现不能选择类型
T
。这是由调用它的上下文选择的。所以我们不能强制执行,或者总是假设
T=StructBar

通常,您会做两件事之一:在由
T
实现的trait中为
T
提供构造函数接口

像将
new()
移到trait中这样的操作对我没有帮助,因为实现TraitBar的新结构可能会将不同的参数移到new()中

即使您可以这样做,编译器如何知道
FooHolder::new()
中需要哪些参数?在这里,变量数量超出了您的能力范围(请参阅),因此告诉编译器根据
T
接受不同数量的参数是不现实的。但是,我们可以通过定义构造参数的关联类型来模拟这种情况。在下面的代码中,我冒昧地使标识符更加惯用(
Struct
Trait
,因为前缀只会引入噪声)

我们的
Bar
定义如下:

struct Bar {
    var: i32,
}

impl Foo for Bar {
    type Params = i32;

    fn foo(&self) -> i32 {
        self.var
    }

    fn new(params: Self::Params) -> Self {
        Bar { var: params }
    }
}
我们的
FooHolder
现在可以构造
T
类型的值:

struct FooHolder<T: Foo> {
    myfoo: T,
}

impl<T: Foo> FooHolder<T> {
    fn new(params: T::Params) -> FooHolder<T> {
        FooHolder { myfoo : T::new(params) }
    }
}
当不需要参数来构造
T
时,我们可以依赖
Default
特性:

impl<T: Foo + Default> Default for FooHolder<T> {
    fn default() -> Self {
        FooHolder { myfoo: T::default() }
    }
}

非常感谢。这是非常彻底的,正是我想要的。
let aaa = FooHolder::<Bar>::new(5);
impl<T: Foo + Default> Default for FooHolder<T> {
    fn default() -> Self {
        FooHolder { myfoo: T::default() }
    }
}
impl<T> FooHolder<T> {
    fn new(foo: T) -> Self {
        FooHolder { myfoo: foo }
    }
}