Только что понял, что мне не нужно указывать тип:
fn mut_tuple_to_iter(v:&mut ((), i32)) ->impl Iterator<Item=&mut dyn D> {
once(&mut v.0 as _).chain(once(&mut v.1 as _))
}
будет работать. Это делает его гораздо менее уродливым!
Конечно, макрос очень поможет:
macro_rules! chained_elements {
($exp: expr) => {
core::iter::once($exp as _)
};
($exp: expr, $($rest:tt)*) => {
core::iter::once($exp as _)
.chain(chained_elements!($($rest)*))
}
}
Теперь вы можете написать
use core::iter::once;
trait D {}
impl D for () {}
impl D for i32 {}
macro_rules! chained_elements {
($exp: expr) => {
core::iter::once($exp as _)
};
($exp: expr, $($rest:tt)*) => {
core::iter::once($exp as _)
.chain(chained_elements!($($rest)*))
}
}
fn mut_tuple_to_iter(v: &mut ((), i32)) -> impl Iterator<Item = &mut dyn D> {
chained_elements!(&mut v.0, &mut v.1)
}
Детская площадкассылка
Обсуждение
Я давно исследую пространство проектирования в ржавчине, но в некоторых случаях вышеизложенное является единственным решением.
Причинаиз этого следует, что когда вам нужно использовать объекты признаков (например, для уменьшения общего взрыва), так как call-by-value не является опцией (пока), call-by-mutable-reference - лучшая вещь, которую вы можете иметь. В таких случаях картина, подобная приведенной выше, кажется неизбежной.