“预期类型参数,找到结构" [英] "expected type parameter, found struct"

查看:35
本文介绍了“预期类型参数,找到结构"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用 Rust 来处理特性,但我遇到了一个问题.这是一些代码:

I've been messing around with traits using Rust and I've come across a problem. Here's some code:

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
}

这会产生错误:

error[E0308]: mismatched types
  --> src/main.rs:11:18
   |
11 |     let foo: B = Foo; // 2. THIS WILL NOT WORK
   |                  ^^^ expected type parameter, found struct `Foo`
   |
   = note: expected type `B`
              found type `Foo`

error[E0308]: mismatched types
  --> src/main.rs:12:32
   |
12 |     let foo_vec: Vec<B> = vec![Foo]; // 3. THIS WILL NOT WORK
   |                                ^^^ expected type parameter, found struct `Foo`
   |
   = note: expected type `_`
              found type `Foo`

为什么不 #2 &#3 工作?我如何让编译器知道 Foo 实际上有一个 Bar impl?

Why won't #2 & #3 work? How can I let the compiler know that Foo does in fact have a Bar impl?

另一个例子:

struct Foo<B: Bar> {
    bar: Option<B>,
}

struct Foo2;

trait Bar {}

impl<B: Bar> Bar for Foo<B> {}

impl Bar for Foo2 {}

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

fn circle_vec<B: Bar>() {
    bar(Foo2); // 1. WORKS
    Foo { bar: Some(Foo { bar: None }) }; // 2. WILL NOT WORK
}

这会给我这个错误:

error[E0282]: type annotations needed
  --> src/main.rs:17:21
   |
17 |     Foo { bar: Some(Foo { bar: None }) }; // 2. WILL NOT WORK
   |                     ^^^ cannot infer type for `B`

推荐答案

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

You have two different problems so I guess I'll write two different answers.

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

In your first code sample, 2 and 3 don't work because B is an input type parameter; it is the caller of barr that decides what B is. However, you are trying to force it to be Foo.

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

Let's suppose we have another implementation of Bar:

struct Quux;

impl Bar for Quux {}

假设我们像这样调用 barr:

And let's suppose we call barr like this:

barr::<Quux>()

barr 基本上会被编译为:

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

FooQuux 不兼容,VecVec 不兼容也兼容.

Foo and Quux are not compatible, and Vec<Foo> and Vec<Quux> are not compatible either.

如果您尝试创建任意 Bar 对象的向量,则需要以非通用方式使用 Bar.由于特征类型没有大小,你不能直接将它们存储在 Vec 中,所以你必须使用 Vec>, Vec<&Bar> 或其他包装指针的类型.

If you're trying to create a vector of arbitrary Bar objects, you need to use Bar in a non-generic way. As trait types are unsized, you can't store them directly in a Vec, so you must use Vec<Box<Bar>>, Vec<&Bar> or some other type that wraps a pointer.

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

<小时>

在您的第二个代码示例中,错误是 None 的类型为 Option,并且编译器无法为 推断适当的类型.我们可以像这样显式指定 T:


In your second code sample, the error is that None has the type Option<T>, and the compiler is unable to infer an appropriate type for T. We can explicitly specify T like this:

fn circle_vec<B: Bar>() {
    bar(Foo2);
    Foo {
        bar: Some(Foo { bar: None::<Foo2> }),
    };
}

这篇关于“预期类型参数,找到结构"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆