错误:无法推断出有关`_`的足够类型信息; 需要输入注释或通用参数绑定

Fiz*_*zer 0 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: 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();
}
Run Code Online (Sandbox Code Playgroud)

(游乐场)

错误是:

<anon>:32:13: 36:22 error: unable to infer enough type information about `_`; type annotations or generic parameter binding required [E0282]
<anon>:32     let t = Test::new();
Run Code Online (Sandbox Code Playgroud)

我对Rust在推断特征类型方面遇到的问题感到困惑,以及如何指定它想要的内容.也就是说,我不确定这是否正确,因为我遇到了Sized问题:

let t = Test::new() as Test<Foo,Bar<Foo>>;
Run Code Online (Sandbox Code Playgroud)

错误:

<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>>;
Run Code Online (Sandbox Code Playgroud)

我有两个主要问题:

  1. 为什么Rust无法推断出特征类型Test<A,B<A>>
  2. 使此代码有效的解决方案是什么?

Chr*_*son 6

简短的回答是你没有告诉它使用什么类型.

解释你的声明:

pub trait Foo {}
Run Code Online (Sandbox Code Playgroud)

"有一个特点Foo"

pub trait Bar<A: Foo> {}
Run Code Online (Sandbox Code Playgroud)

"如果你给我一种A实施的类型Foo,我可以给你一个特质Bar<A>."

pub struct Test<A, B>
    where A: Foo,
          B: Bar<A> {}
Run Code Online (Sandbox Code Playgroud)

"如果你给我种A,它实现了Foo,并且B,它实现了Bar<A>,我给你一个类型Test<A,B>.

let t = Test::new();
Run Code Online (Sandbox Code Playgroud)

"让我成为一个Test".这是问题 - Test不是一个类型,它是一个模板,用于给出一个给定两种类型的类型(有一些限制).在上面的示例中,您没有提供任何此类类型,只是缩小了类似的类型.

要实际使用Test,您需要提供以下类型:

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();
}
Run Code Online (Sandbox Code Playgroud)

(游乐场)

  • 很好的答案.另一件事是编译器的推理范围非常高 - 所以如果你的代码满足推理机制,你可能会省略类型参数..通过使用`add_foo`和`add_bar`方法,如:https:// play. rust-lang.org/?gist=c507bbcd0ad94bfa892c09e097354b5b&version=stable&backtrace=0 (2认同)