Как создать вектор универсальных функций в Rust

fn render_task_enter_field<W>(stdout: &mut W)
where
    W: Write,
{
    ...
}

Мне нужно добавить эту функцию в вектор. Я буду повторять это и вызывать каждую функцию.

Я пробовал Vec<fn(&mut impl Write)>, но не работает

Как я могу вызвать свою функцию? Я хочу передать в эту функцию описанную ниже переменную.

let mut stdout = stdout()
        .into_raw_mode()
        .expect("Cannot run raw mode")
        .into_alternate_screen()
        .expect("Cannot run alternate screen");

Я использую ящик Termion

Указатель функции не может быть универсальным. Можете ли вы подробнее рассказать о своем варианте использования?

Chayim Friedman 22.06.2024 21:19

Согласно Как создать неоднородную коллекцию объектов? вам нужно сделать типы однородными для хранения в векторе. Вместо этого, возможно, что-то вроде fn render(stdout: &dyn Write). ИЛИ вам нужно, чтобы W означало одно и то же для всех элементов.

kmdreko 22.06.2024 21:21
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
0
2
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы хотите это:

Vec<Box<dyn Fn(&mut dyn Write)>>

Вектор блоков, содержащий функцию динамического типа, которая принимает динамический объект, реализующий запись.

Вы не можете добавлять в массив общие функции, поскольку на самом деле это просто набор отдельных функций, но вы можете просто заставить его принимать объект типажа в качестве аргумента, чтобы получить тот же эффект.

Полный пример:

use std::io::Write;

fn render_task_enter_field(stdout: &mut dyn Write)
{
}


fn main() {
    let mut k:Vec<Box<dyn Fn(&mut dyn Write)>> = vec![];

    k.push(Box::new(render_task_enter_field));
   
    for m in k {
        m(&mut std::io::stdout());
    }
}

Спасибо за ответ, но у меня еще есть вопрос. Как мне теперь вызвать нажатую функцию? :) Я отредактирую свой вопрос прямо сейчас

Artem Novikov 22.06.2024 21:49

@ArtemNovikov Я добавил пример вызова функции. Box реализует Deref, поэтому обычно его можно рассматривать как внутренний тип. Для вызова функции не требуется ничего особенного.

mousetail 22.06.2024 22:29

С таким же успехом это могло бы быть более эффективно fn(&mut dyn Write).

Chayim Friedman 22.06.2024 23:00

@ChayimFriedman Правда, в этом случае вы не сможете добавить замыкания в массив.

mousetail 23.06.2024 07:50

Вы можете использовать это с mut

fn render_task_enter_field<W: Write + ?Sized>(stdout: &mut W) {
    writeln!(stdout, "Hello, world!").unwrap();
}

fn main() {
    let mut v: Vec<Box<dyn Fn(&mut dyn Write)>> = Vec::new();

    for _ in 0..10 {
        v.push(Box::new(|stdout: &mut dyn Write| {
            render_task_enter_field(stdout);
        }));
    }
}

С таким же успехом это могло бы быть более эффективно fn(&mut dyn Write).

Chayim Friedman 22.06.2024 23:00

Другие вопросы по теме