Rust &引用;应为类型参数,找到结构";

Rust &引用;应为类型参数,找到结构";,rust,Rust,我一直在用锈菌来混淆特性,我遇到了一个问题。下面是一些代码: struct Foo; trait Bar {} impl Bar for Foo {} fn bar<B: Bar>(bar: B) {} fn barr<B: Bar>() { bar(Foo); // 1. THIS WILL WORK let foo: B = Foo; // 2. THIS WILL NOT WORK let foo_vec: Vec<B>

我一直在用锈菌来混淆特性,我遇到了一个问题。下面是一些代码:

struct Foo;

trait Bar {}

impl Bar for Foo {}

fn bar<B: Bar>(bar: B) {}

fn barr<B: Bar>() {
    bar(Foo); // 1. THIS WILL WORK
    let foo: B = Foo; // 2. THIS WILL NOT WORK
    let foo_vec: Vec<B> = vec![Foo]; // 3. THIS WILL NOT WORK
}
这将导致以下错误:

错误[E0282]:需要类型注释
-->src/main.rs:17:21
|
17 | Foo{bar:Some(Foo{bar:None})};//2.行不通
|^^^无法推断'B'的类型`

你有两个不同的问题,所以我想我会写两个不同的答案


在第一个代码示例中,2和3不起作用,因为B是一个输入类型参数;是
barr
的调用者决定了B是什么。但是,您试图将其强制为
Foo

假设我们有另一个
Bar
的实现:

struct Quux;

impl Bar for Quux {}
假设我们这样称呼巴尔:

barr::<Quux>()
fn circle_vec<B: Bar>() {
    bar(Foo2);
    Foo {
        bar: Some(Foo { bar: None::<Foo2> }),
    };
}
Foo
qux
不兼容,
Vec
Vec
也不兼容

如果您试图创建任意
Bar
对象的向量,则需要以非通用方式使用
Bar
。由于特征类型没有大小,您无法将它们直接存储在
Vec
中,因此您必须使用
Vec
Vec
或包装指针的其他类型

fn barr() {
    bar(Foo);
    let foo: Box<Bar> = Box::new(Foo);
    let foo_vec: Vec<Box<Bar>> = vec![Box::new(Foo) as Box<Bar>];
}

最后一个问题,为什么
fn barr(){let foo_vec:vec…}
不起作用?或者它可以工作,而我只是缺少了一些东西?通过使用类型参数,向量的所有元素必须是调用者指定的相同类型,这意味着您不能在向量中存储Foo,因为
B
可能不是
Foo
。要向向量添加元素,您需要类型为
B
,通常作为函数的参数接收(
fn-barr(x:B)
)。这似乎是在使用特征对象,即动态分派。然而,他说“一个人总是可以有一个静态调度的瘦包装器函数来执行动态调度,但反之亦然,这意味着静态调用更灵活。”在这种情况下,实际上有没有一种方法不使用trait对象而只执行静态调度?我还遇到了一个用例,我希望有一个向量来存储实现相同特性的可能不同类型的结构。
fn barr() {
    bar(Foo);
    let foo: Box<Bar> = Box::new(Foo);
    let foo_vec: Vec<Box<Bar>> = vec![Box::new(Foo) as Box<Bar>];
}
fn circle_vec<B: Bar>() {
    bar(Foo2);
    Foo {
        bar: Some(Foo { bar: None::<Foo2> }),
    };
}