Как пометить переменную как статическую ссылку на метод с аргументом типа? - PullRequest
3 голосов
/ 29 марта 2019

Я пытаюсь дать ссылку на статический метод и аргумент типа для Box::new и не смог его скомпилировать.

У меня есть следующая структура:

trait MyTrait {
    fn hello(&self);
}

struct MyStruct;

impl MyTrait for MyStruct {
    fn hello(&self) {
        println!("Hello");
    }
}

В моем основном методе я хочу привести эти структуры к чертам объектов, поместить их в Box и вернуть его как вектор. Мне удалось сделать это так:

fn main() {
    let my_vec = vec![MyStruct];

    let my_trait_vec: Vec<Box<MyTrait>> = my_vec
        .into_iter()
        .map(|x| {
            let boxed: Box<MyTrait> = Box::new(x);
            boxed
        })
        .collect();
}

Я ищу что-то вроде:

let mut my_trait_vec: Vec<Box<MyTrait>> = my_vec.into_iter().map(Box::new::<MyTrait>).collect();

Это не принято компилятором, и он жалуется на неожиданный аргумент типа для Box::new().

Можно ли выполнить эту операцию бокса в одну строку без объявления какой-либо внешней функции?

Детская площадка

1 Ответ

4 голосов
/ 29 марта 2019

Поскольку вы хотите задать тип параметра для типа Box, правильный синтаксис будет Box::<dyn MyTrait>::new, а не Box::new::<dyn MyTrait>.Однако это также не будет работать, так как компилятор попытается привести тип аргумента к Box::new() к dyn MyTrait, прежде чем передать его по значению, что невозможно для динамически изменяемых типов.Сначала вы должны создать блок, и только потом вы можете выполнить принудительное приведение к размеру, чтобы у вас был хороший код.Вот альтернатива, которая по сути та же самая, просто написана немного более кратко:

let mut my_trait_vec: Vec<Box<dyn MyTrait>> = my_vec
    .into_iter()
    .map(|x| Box::new(x) as Box<dyn MyTrait>)
    .collect();

Еще один вариант - определить вспомогательную функцию, например,

fn into_boxed_trait<T>(value: T) -> Box<dyn MyTrait>
where
    T: MyTrait + 'static,
{
    Box::new(value)
}

Это позволит вамнаписать

let mut my_trait_vec: Vec<_> = my_vec
    .into_iter()
    .map(into_boxed_trait)
    .collect();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...