实现通用特征的对象的Vec

时间:2019-01-28 21:26:20

标签: rust

我正在构建一个命令行应用程序。我具有以下特征:

trait ValidatedCommand {
    type Output;
    fn run() -> Result<Self::Output, std::io::Error>;
}

,我有以下两种实现方式:

struct First;
impl ValidatedCommand for First {
    type Output = i32;
    fn run() -> Result<i32, std::io::Error> {
        Ok(1)
    }
}
impl First {
    fn new() -> First {
        First {}
    }
}

struct Second;
impl ValidatedCommand for Second {
    type Output = String;
    fn run() -> Result<String, std::io::Error> {
        Ok(String::from("hello"))
    }
}
impl Second {
    fn new() -> Second {
        Second {}
    }
}

这两个结构都实现了特征,一个返回String,另一个返回i32

我正在尝试创建具有该特征的Vec,但是我不确定该如何去做。我尝试了以下方法:

fn main() {
    let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];

playground

哪个错误

error[E0191]: the value of the associated type `Output` (from the trait `ValidatedCommand`) must be specified
  --> src/main.rs:33:23
   |
2  |     type Output;
   |     ------------ `Output` defined here
...
33 |     let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
   |                       ^^^^^^^^^^^^^^^^^^^^ associated type `Output` must be specified

error[E0277]: the size for values of type `dyn ValidatedCommand` cannot be known at compilation time
  --> src/main.rs:33:19
   |
33 |     let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `dyn ValidatedCommand`
   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
   = note: required by `std::vec::Vec`

error[E0038]: the trait `ValidatedCommand` cannot be made into an object
  --> src/main.rs:33:19
   |
33 |     let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ValidatedCommand` cannot be made into an object
   |
   = note: method `run` has no receiver

error[E0308]: mismatched types
  --> src/main.rs:33:52
   |
33 |     let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
   |                                                    ^^^^^^^^^^^^ expected trait ValidatedCommand, found struct `First`
   |
   = note: expected type `dyn ValidatedCommand`
              found type `First`

error[E0277]: the size for values of type `dyn ValidatedCommand` cannot be known at compilation time
  --> src/main.rs:33:47
   |
33 |     let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `dyn ValidatedCommand`
   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
   = note: required by `std::slice::<impl [T]>::into_vec`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0277]: the size for values of type `dyn ValidatedCommand` cannot be known at compilation time
  --> src/main.rs:33:47
   |
33 |     let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `dyn ValidatedCommand`
   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
   = note: slice and array elements must have `Sized` type
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0038]: the trait `ValidatedCommand` cannot be made into an object
  --> src/main.rs:33:47
   |
33 |     let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ValidatedCommand` cannot be made into an object
   |
   = note: method `run` has no receiver
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0277]: the size for values of type `dyn ValidatedCommand` cannot be known at compilation time
  --> src/main.rs:33:47
   |
33 |     let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `dyn ValidatedCommand`
   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
   = note: required by `std::vec::Vec`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0038]: the trait `ValidatedCommand` cannot be made into an object
  --> src/main.rs:33:47
   |
33 |     let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ValidatedCommand` cannot be made into an object
   |
   = note: method `run` has no receiver
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

我在想,也许有一种方法可以利用关联的类型,但是我不知道该怎么做。

是否有一种方法可以编译此向量?

0 个答案:

没有答案