Generics 错误:无法推断有关``的足够类型信息;需要类型批注或泛型参数绑定
为通用标题道歉 下面是一些示例代码:Generics 错误:无法推断有关``的足够类型信息;需要类型批注或泛型参数绑定,generics,rust,Generics,Rust,为通用标题道歉 下面是一些示例代码: use std::marker::PhantomData; pub trait Foo { fn foo(&self); } pub trait Bar<A: Foo> { fn bar(&self, a: A); } pub struct Test<A, B> where A: Foo, B: Bar<A> { _phantom_r: Phanto
use std::marker::PhantomData;
pub trait Foo {
fn foo(&self);
}
pub trait Bar<A: Foo> {
fn bar(&self, a: A);
}
pub struct Test<A, B>
where A: Foo,
B: Bar<A>
{
_phantom_r: PhantomData<A>,
bars: Vec<B>,
}
impl<A, B> Test<A, B>
where A: Foo,
B: Bar<A>
{
pub fn new() -> Test<A, B> {
Test {
_phantom_r: PhantomData,
bars: Vec::new(),
}
}
pub fn add_bar(&mut self, b: B) {
self.bars.push(b);
}
}
fn main() {
let t = Test::new();
}
错误:
<anon>:36:28: 36:46 error: the trait `core::marker::Sized` is not implemented for the type `Foo` [E0277]
<anon>:36 let t = Test::new() as Test<Foo,Bar<Foo>>;
:36:28:36:46错误:没有为类型'Foo`[E0277]实现trait'core::marker::Sized'
:36让t=Test::new()作为测试;
我有两个主要问题:
测试的特征类型
简单的回答是,您没有告诉它使用哪种类型 解释你的声明:
pub trait Foo {}
“有一个特征Foo
”
“如果你给我类型
A
,它实现Foo
,和B
,它实现Bar),简单的回答是你没有告诉它使用什么类型
解释你的声明:
pub trait Foo {}
“有一个特征Foo
”
“如果您给我类型A
,它实现Foo
,和B
,它实现Bar),您可以将第一个错误归结为:
fn main() {
let v = Vec::new();
}
这里的问题是编译器无法确定向量将包含哪些具体类型。在本例中,您创建了一个结构(Test
),该结构可以在不传递a
和B
的具体类型的情况下创建,但基本推理是相同的
第二个问题是相关的。Foo
和Bar
都不是编译时已知大小的具体类型。尝试在需要固定大小(由size
trait表示)的位置使用它们将失败
实例化类型时,必须知道类型的大小,这是通过提供具体类型来代替泛型类型参数来实现的 您可以将第一个错误归结为:
fn main() {
let v = Vec::new();
}
这里的问题是编译器无法确定向量将包含哪些具体类型。在本例中,您创建了一个结构(Test
),该结构可以在不传递a
和B
的具体类型的情况下创建,但基本推理是相同的
第二个问题是相关的。Foo
和Bar
都不是编译时已知大小的具体类型。尝试在需要固定大小(由size
trait表示)的位置使用它们将失败
实例化类型时,必须知道类型的大小,这是通过提供具体类型来代替泛型类型参数来实现的 关于已接受答案的说明-已接受答案涵盖了识别特征的问题,但该线索中有一些注释解释了该问题的其他细节。为了便于阅读,我在这里总结了其中一个(因为评论有点难读)
(当您使用上面代码中的特征时使用)将无法处理向量上的多个具体类型
例如,以这个例子:
trait Foo {
fn method(&self) -> String;
}
impl Foo for u8 {
fn method(&self) -> String {
format!("u8: {}", *self)
}
}
impl Foo for String {
fn method(&self) -> String {
format!("string: {}", *self)
}
}
struct Test<T: Foo> {
foos: Vec<T>,
}
impl<T:Foo> Test<T> {
pub fn do_something(&self, x: T) {
self.foos.push(x);
}
}
fn main() {
let x = 5u8;
let y = "Hello".to_string();
let t = Test {foos:Vec::new()};
t.do_something(x);
t.do_something(y);
}
它会起作用的。main()
函数根本不需要更改(除了删除向量之外),它完全与导致静态调度(显然)不起作用的向量有关
在这种情况下,我相信它会起作用——但我对它还不够熟悉,还没有给出任何深入的答案/示例。希望这对未来的读者有所帮助。关于已接受答案的说明-已接受答案涵盖了识别特征的问题,但该线索中有一些注释解释了该问题的其他细节。为了便于阅读,我在这里总结了其中一个(因为评论有点难读)
(当您使用上面代码中的特征时使用)将无法处理向量上的多个具体类型
例如,以这个例子:
trait Foo {
fn method(&self) -> String;
}
impl Foo for u8 {
fn method(&self) -> String {
format!("u8: {}", *self)
}
}
impl Foo for String {
fn method(&self) -> String {
format!("string: {}", *self)
}
}
struct Test<T: Foo> {
foos: Vec<T>,
}
impl<T:Foo> Test<T> {
pub fn do_something(&self, x: T) {
self.foos.push(x);
}
}
fn main() {
let x = 5u8;
let y = "Hello".to_string();
let t = Test {foos:Vec::new()};
t.do_something(x);
t.do_something(y);
}
它会起作用的。main()
函数根本不需要更改(除了删除向量之外),它完全与导致静态调度(显然)不起作用的向量有关
在这种情况下,我相信它会起作用——但我对它还不够熟悉,还没有给出任何深入的答案/示例。希望这对未来的读者有所帮助。回答得不错。另一件事是编译器的推理范围相当高,因此如果代码满足推理机制,则可能会忽略类型参数。。通过使用add_foo
和add_bar
方法,如下所示:谢谢你们的评论!在回答克里斯时,我最大的问题就是你把西蒙带大了!我的问题是,我无法提供像Chris示例中那样的具体类型,即:MyA
和MyB
结构。我之所以使用traits,是因为我没有一个具体的类型——我添加了多种类型,就像Simon的例子一样。尽管如此,也许我的设计是错误的。不可能接受在单个函数中实现同一接口的多个具体类型吗?也就是说,MyB
和MyC
implementFoo
,以及Test::add_bar()
implements都接受aB
,但似乎add_bar()
只接受一个具体类型,而不是类型上的特征。思想?也许我从根本上误解了Rust对Traits的实现(我认为它们更像是Go接口)@FizzBazer也许你想要一个?@Shepmaster似乎是这样,谢谢!对于其他人来说,我想我发现了设计上的一个问题。静态分派通过创建备用的、特定于类型的方法来工作——但这与向量不兼容。如果要将它们存储在数据结构中(我想象vector、hashmap等),则不能在编译时通过静态分派进行复制。因此,如果使用向量,显然需要动态调度。我还没有使用动态调度,所以
struct MyA {}
impl Foo for MyA {
fn foo(&self) { println!("MyA::foo"); }
}
struct MyB {}
impl Bar<MyA> for MyB {
fn bar(&self, a: MyA) { println!("MyB::bar"); }
}
fn main() {
let test = Test::<MyA, MyB>::new();
}
fn main() {
let v = Vec::new();
}
trait Foo {
fn method(&self) -> String;
}
impl Foo for u8 {
fn method(&self) -> String {
format!("u8: {}", *self)
}
}
impl Foo for String {
fn method(&self) -> String {
format!("string: {}", *self)
}
}
struct Test<T: Foo> {
foos: Vec<T>,
}
impl<T:Foo> Test<T> {
pub fn do_something(&self, x: T) {
self.foos.push(x);
}
}
fn main() {
let x = 5u8;
let y = "Hello".to_string();
let t = Test {foos:Vec::new()};
t.do_something(x);
t.do_something(y);
}
struct Test {
}
impl Test {
pub fn do_something<T: Foo>(&self, x: T) {
x.method();
}
}