Есть ли лучший / менее многословный способ?
На самом деле не существует способа сделать это менее многословным.Поскольку вы используете объекты признаков, вам нужно сообщить компилятору, что элементы векторов dyn Function
, а не конкретный тип.Компилятор не может просто сделать вывод, что вы имели в виду dyn Function
объекты признаков, потому что могли существовать другие признаки, которые оба Add
и Multiply
реализуют.
Вы не можете абстрагировать вызовы к Box::new
или.Чтобы это работало, вам нужно как-то отобразить разнородную коллекцию, что невозможно в Rust.Однако, если вы много пишете об этом, вы можете рассмотреть возможность добавления вспомогательных функций конструктора для каждого конкретного impl
:
impl Add {
fn new() -> Add {
Add {}
}
fn new_boxed() -> Box<Add> {
Box::new(Add::new())
}
}
Идиоматично включать конструктор new
везде, где это возможно, но это также распространеновключите альтернативные удобные конструкторы.
Это делает построение вектора немного менее шумным:
let funcs: Vec<Box<dyn Function>> = vec!(Add::new_boxed(), Multiply::new_boxed()));
Что такое вынос с объектами признаков в этом случае?
При использовании динамической диспетчеризации всегда наблюдается небольшое снижение производительности.Если все ваши объекты одного типа, они могут быть плотно упакованы в памяти, что может быть намного быстрее для итерации.В общем, я бы не стал сильно беспокоиться об этом, если вы не создаете библиотечный ящик или если вы действительно хотите выжать последнюю наносекунду производительности.