Generics Rust编译器无法推断有关泛型类型的足够信息

Generics Rust编译器无法推断有关泛型类型的足够信息,generics,rust,Generics,Rust,我正在学习生锈,遇到了类似的东西 struct A<T> { some_vec: Vec<T>, pub secret: &'static str } struct B{} struct C{} impl B { fn foo<T>(&self) { let bar: A<T> = A { some_vec: Vec::new(),

我正在学习生锈,遇到了类似的东西

struct A<T> {
    some_vec: Vec<T>,
    pub secret: &'static str
}

struct B{}

struct C{}

impl B {
    fn foo<T>(&self) {

        let bar: A<T> = A { 
            some_vec: Vec::new(), 
            secret: "123" 
        };

        println!("The secret is {}", bar.secret);
    }
}

impl C {
    fn foo<T>(&self) {
        let b = B{};
        b.foo();
    }
}

fn main() {
    let c = C{};
    c.foo();
}

我看到过关于相同错误消息的帖子,但我无法找到这种情况下的解决方案。我缺少哪些信息(与
b.foo()
)来指定?

通常,泛型函数会在其参数的类型中使用其类型参数。在这种情况下,编译器可以从调用的参数类型推断类型参数

但是,在您的例子中,
B::foo
C::foo
没有使用
t
的任何参数。因此,每个调用都需要显式地为
T
指定一个具体类型。这是通过在函数名之后、括号之前添加
(其中
X
是一种类型)来实现的

C::foo
中,您可能希望将
C::foo
T
转发到
B::foo
,因此您可以编写:

impl C {
    fn foo<T>(&self) {
        let b = B {};
        b.foo::<T>();
    }
}

由于类型推断对许多人来说是一种新奇的东西,让我们更深入地解释一下

本质上,类型推断有点像你在杂志上玩的那些“迷宫”游戏:

在左手边有很多未知类型的地方,可以连接到右手边的一些已知类型。如何?好吧,通过检查类型之间的关系

最简单的关系(无需猜测)是1度关系:

let x: String = "Hello, World".into();
在Rust中,我们知道
into()
来自
into
特性,该特性由
&str
实现,但是哪个
T
?嗯,
into()
返回一个
T
,表达式的类型应该是
字符串,因此它必须是
into

为了解决类型推断问题,编译器将因此在需要推断类型的位置和已知类型之间建立某种关系图(在Rust中,函数签名必须是显式的,因此不必搜索太远),然后尝试一点一点地推断类型


让我们检查一下当前的用例:

fn main() {
    let c = C{};
    c.foo();
}
这里,
c.foo()调用
C::foo()
:我们需要推断
T
。我们有什么信息?没有一个废话。娜达

在这种情况下,由于无法解决问题,编译器退出并询问您(开发人员)希望
T
成为什么。您可以通过多种方式指定它:

  • 一般的方法是使用所谓的“turbofish”操作符
    ::
    ,如
    c.foo::()
  • 在无法推断结果的特定情况下,您可以简单地将一个类型归因于左侧变量,如
    let x:i32=
  • 需要注意的是,通常情况下,您不需要提供完整的类型,并且可以使用
    字符来删除部分类型,如
    let x:Vec=
    c.foo::()
    当然,如果编译器有足够的信息自行推断

您必须调用
b.foo::()
c.foo::()
(或任何其他类型,而不是
i32
)。您实际上从未指定过此类型参数。。。现在懒得回答这个问题。。。对不起:谢谢你丢失的那块!如果有人对此做出了真正的回答,我会将其标记为已解决
fn main() {
    let c = C{};
    c.foo();
}