, если что-то вроде этого кода может работать
Зависит от того, насколько "как" вы имеете в виду.Это похоже, работает и не требует специального итератора;таким образом отвечая всем вашим требованиям:
fn depth_first_metadata_iter(&self) -> Box<Iterator<Item = &i64> + '_> {
Box::new({
self.children
.iter()
.flat_map(|child| child.depth_first_metadata_iter())
.chain(self.metadata.iter())
})
}
По сути, это та же проблема, что показана в
Поставьте себя на место компилятора некоторое время.Ваш оригинальный код говорит: «Я собираюсь вернуть конкретный тип итератора, но я не собираюсь говорить точный тип».Компилятор все еще должен иметь возможность определить этот тип, поэтому давайте будем компилятором:
let a = self.children.iter();
// std::slice::Iter<'_, Box<Node>>
let cls = |child| child.depth_first_metadata_iter();
// Fn(&Box<Node>) -> ?X?
let b = a.flat_map(cls);
// FlatMap<Iter<'_, Box<Node>>, ?X?, Fn(&Box<Node>) -> ?X?>
let d = self.metadata.iter();
// std::slice::Iter<'_, i64>
b.chain(d);
// Chain<FlatMap<Iter<'_, Box<Node>>, ?X?, Fn(&Box<Node>) -> ?X?>, Iter<'_, i64>>
Этот конечный результат является возвращаемым значением, поэтому у нас есть уравнение:
Chain<FlatMap<Iter<'_, Box<Node>>, ?X?, Fn(&Box<Node>) -> ?X?>, Iter<'_, i64>> === ?X?
AFAIK, невозможно выполнить алгебру уровня типа, чтобы решить для ?X?
, таким образом, вы получите ошибку.
Изменение типа возвращаемого значения в объекте с признаками в штучной упаковке замыкает всю необходимую логику и вызываетконкретный тип бетона.
стратегическое размещение где-то аннотации типа
Я не верю, что это так.Если это так, это будет означать, что алгебра разрешима, но компилятор не достаточно умен, чтобы ее решить.Хотя это, несомненно, верно в других ситуациях, я не думаю, что это здесь.
Я не думаю, что это замечательное решение, так как в нем будет многокрошечные выделения.Я бы предположил (но не проверял), что пользовательский итератор, использующий структуру данных стека, будет более эффективным.
Срединной точкой было бы построение всего набора узлов:
impl Node {
fn depth_first_metadata_iter(&self) -> impl Iterator<Item = &i64> + '_ {
self.x().into_iter()
}
fn x(&self) -> Vec<&i64> {
fn x_inner<'a>(node: &'a Node, v: &mut Vec<&'a i64>) {
for c in &node.children {
x_inner(c, v)
}
v.extend(&node.metadata);
}
let mut v = Vec::new();
x_inner(self, &mut v);
v
}
}