当前位置: 首页 > 知识库问答 >
问题:

为什么我不能在数组声明中使用类型推断?

卢勇
2023-03-14

我声明了一个自定义trait Animal的数组,以便在Rust中试验多态性,但是编译器似乎在第一个元素的子类型上进行类型推断:

fn main() {
    let animals = [Cat, Dog, Cat, Lion, Dog, Lion];
    for single_animal in animals {
        single_animal.talk();
    }
}

trait Animal {
    fn talk(&self);
}

struct Cat;
struct Dog;
struct Lion;

impl Animal for Cat {
    fn talk(&self) { 
        println!("Je miaule !");
    }
}

impl Animal for Dog {
    fn talk(&self) { 
        println!("J'aboie !");
    }
}

impl Animal for Lion {
    fn talk(&self) {
        println!("Je rugit !");
    }
}

编译器抱怨第一个元素是< code>Cat而不是其他元素:

error: mismatched types [--explain E0308]
 --> src/main.rs:3:25
  |>
3 |>     let animals = [Cat, Dog, Cat, Lion, Dog, Lion];
  |>                         ^^^ expected struct `Cat`, found struct `Dog`
note: expected type `Cat`
note:    found type `Dog`

error: mismatched types [--explain E0308]
 --> src/main.rs:3:35
  |>
3 |>     let animals = [Cat, Dog, Cat, Lion, Dog, Lion];
  |>                                   ^^^^ expected struct `Cat`, found struct `Lion`
note: expected type `Cat`
note:    found type `Lion`

error: mismatched types [--explain E0308]
 --> src/main.rs:3:41
  |>
3 |>     let animals = [Cat, Dog, Cat, Lion, Dog, Lion];
  |>                                         ^^^ expected struct `Cat`, found struct `Dog`
note: expected type `Cat`
note:    found type `Dog`

error: mismatched types [--explain E0308]
 --> src/main.rs:3:46
  |>
3 |>     let animals = [Cat, Dog, Cat, Lion, Dog, Lion];
  |>                                              ^^^^ expected struct `Cat`, found struct `Lion`
note: expected type `Cat`
note:    found type `Lion`

error: the trait bound `[Cat; 6]: std::iter::Iterator` is not satisfied [--explain E0277]
 --> src/main.rs:4:5
  |>
4 |>     for single_animal in animals {
  |>     ^
note: `[Cat; 6]` is not an iterator; maybe try calling `.iter()` or a similar method
note: required by `std::iter::IntoIterator::into_iter`

向数组中添加Animal类型也不能解决问题。因为这一次我得到了更多的错误:

error: mismatched types [--explain E0308]
 --> src/main.rs:3:27
  |>
3 |>     let animals: Animal = [Cat, Dog, Cat, Lion, Dog, Lion];
  |>                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait Animal, found array of 6 elements
note: expected type `Animal`
note:    found type `[Cat; 6]`

error: the trait bound `Animal: std::marker::Sized` is not satisfied [--explain E0277]
 --> src/main.rs:3:9
  |>
3 |>     let animals: Animal = [Cat, Dog, Cat, Lion, Dog, Lion];
  |>         ^^^^^^^
note: `Animal` does not have a constant size known at compile-time
note: all local variables must have a statically known size

error: the trait bound `Animal: std::marker::Sized` is not satisfied [--explain E0277]
 --> src/main.rs:4:5
  |>
4 |>     for single_animal in animals {
  |>     ^
note: `Animal` does not have a constant size known at compile-time
note: required by `std::iter::IntoIterator::into_iter`

error: the trait bound `Animal: std::iter::Iterator` is not satisfied [--explain E0277]
 --> src/main.rs:4:5
  |>
4 |>     for single_animal in animals {
  |>     ^
note: `Animal` is not an iterator; maybe try calling `.iter()` or a similar method
note: required by `std::iter::IntoIterator::into_iter`

共有2个答案

干旺
2023-03-14

这是因为狮子都是不同的类型,你只能在数组中有一个。

你可以像卢卡斯建议的那样使用trait对象,但你所追求的可能更容易实现(trait对象不是我推荐给Rust初学者的东西),有一个常见的动物枚举:

use self::Animal::*;

fn main() {
    let animals = [Cat, Dog, Cat, Lion, Dog, Lion];
    for single_animal in animals.iter() {
        single_animal.talk();
    }
}

trait AnimalSkills {
    fn talk(&self);
}

enum Animal {
    Cat,
    Dog,
    Lion
}

impl AnimalSkills for Animal {
    fn talk(&self) {
        match *self {
            Cat => println!("Je miaule !"),
            Dog => println!("J'aboie !"),
            Lion => println!("Je rugit !")
        }
    }
}

另请注意,您需要调用. iter()才能迭代数组。

邹野
2023-03-14

Rust数组是均匀的,这意味着其中的每个元素都具有相同的类型。因此,不能将数组与<code>Dog</code>s和<code>Cat</code>s组合。但在您的例子中,您可以拥有一个充满所谓“trait对象”的数组

你必须明确地告诉编译器你想要一个包含trait对象的数组。编译器根据初始值设定项中的第一个元素推断数组的类型,因此让我们显式转换该元素:

let animals = [&Cat as &Animal, &Dog, &Cat, &Lion, &Dog, &Lion];

请注意,我们还添加了一个< code >

 类似资料:
  • 我正在标准中寻找对这一事实的正式解释。我找到了3.9.1/9所说的,并试图用该部分给出解释。 第3.9.1/9节,N3797: void类型有一组空值。void类型是不完整的类型,无法完成。它用作不返回值的函数的返回类型。任何表达式都可以显式转换为cv void类型(5.4)。void类型的表达式只能用作表达式语句(6.2)、逗号表达式的操作数(5.18)以及?的第二个或第三个操作数:(5.16)

  • 我习惯像这样声明数组内联: 为什么我不能对函数执行相同的操作?假设我有一个类,其中包含and 方法,这是有效的: 但是,这不是: 它不喜欢内联数组声明,编译器错误是“不能创建函数的泛型数组” 编辑 我认为我的问题不是建议的副本,因为我想使用数组初始值设定项语法静态定义一组函数

  • 问题内容: 为什么不能在Java中将类声明为静态类? 问题答案: 只有嵌套的类可以是静态的。这样,你可以使用嵌套类而无需外部类的实例。

  • 我的朋友们,我的项目有三节课 主类: 首先,当我在类中实例时,java使结构如下所示:structure 我的意思是,当我们在类中实例类时,java逐行读取类,例如: 因为中有3个变量,所以我们可以说,当我们实例类时,我们有5个变量。 例如,我们有字符串、int、int、int、int来表示。我的问题是为什么我们不能直接访问或或? 例如,对于initialize name,我们可以使用以下代码:,

  • 问题内容: 我读到从Java 7开始,像在第一条语句中那样在右侧指定类型来创建Collections是不好的样式,因为编译器可以从左侧推断类型。 我的问题是,当像这样初始化列表时,编译器找不到类型,并且我收到未经检查的类型警告: 问题答案: 编译器不会 推断 类型,因为您正在实例化 raw 。但是它足够聪明,可以警告您在使用此(原始)对象时可能会出现问题。 值得一提的是此警告背后的原因。由于类型擦

  • 问题内容: 我试图找到为什么不能将类创建为静态类的原因?喜欢: 问题答案: 在Java中,关键字通常将一个方法或字段标记为不存在,而不是每个类实例一次,而是一次。一个类一旦存在就已经存在,因此实际上,所有类都以这种方式是“静态的”,并且所有对象都是该类的实例。 确实对 内部 类具有含义,这是完全不同的:通常,内部类实例可以访问与其绑定的外部类实例的成员,但是如果内部类为,则它没有这样的引用并且可以