Как я могу добавить функции с различными аргументами и типами возвращаемых данных в вектор? - PullRequest
2 голосов
/ 05 марта 2020

Я пытаюсь добавить функции с разными аргументами к вектору.

fn f1() {
    println!("Hello, World!");
}
fn f2(s: &str) -> String {
    String::from(s)
}
fn f3(i: i32) {
    println!("{}", i);
}

fn main() {
    let v = vec![f1, f3, f2];
}

Но это выдает ошибку:

error[E0308]: mismatched types
  --> src/main.rs:12:22
   |
12 |     let v = vec![f1, f3, f2];
   |                      ^^ incorrect number of function parameters
   |
   = note: expected type `fn() {f1}`
           found fn item `fn(i32) {f3}`

Есть ли способ Я могу сделать эту работу?

1 Ответ

5 голосов
/ 05 марта 2020

Ошибка возникает из-за того, что векторы предназначены только для хранения однородных данных, т.е. каждый элемент вектора должен быть одного типа. Чтобы решить эту проблему, вы можете, например, использовать вектор перечислений:

enum E {
    F1(fn()),
    F2(fn(&str) -> String),
    F3(fn(i: i32)),
}

fn f1() {
    println!("Hello, World!");
}
fn f2(s: &str) -> String {
    String::from(s)
}
fn f3(i: i32) {
    println!("{}", i);
}

fn main() {
    let v = vec![E::F1(f1), E::F3(f3), E::F2(f2)];
    for func in v {
        match func {
            E::F1(f) => f(),
            E::F2(f) => println!("{}", f("foo")),
            E::F3(f) => f(2),
        } 
    }
}

Выход

Hello, World!
2
foo

Или вы можете использовать контейнер, созданный специально для хранения разнородных data, он же кортеж:

fn main() {
    let v = (f1, f3, f2);
    v.0();
    v.1(2);
    println!("{}", v.2("foo"));
}

Выход

Hello, World!
2
foo
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...