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> }),
};
}