Уплощение вложенной структуры - PullRequest
0 голосов
/ 25 ноября 2018

Ищет мудрость в исправлении этой проблемы с проверкой заимствований и пожизненной версией Rust.Я пытаюсь сгладить общую вложенную структуру (в impl итератор или Vec).Возможно, это всего лишь несколько шагов, и они не работают:

fn iter_els(prev_result: Vec<&El>) -> Vec<&El> {
    // Iterate over all elements from a tree, starting at the top-level element.
    let mut result = prev_result.clone();

    for el in prev_result {
        for child in &el.children {
            result.push(&child.clone());
        }
        result.extend(iter_els(&el.children));
    }
    result
}

Вы заметите, что немедленное исключение, которое возникает, заключается в том, что iter_els ожидает Vec ссылок, а не сам реф.Когда мы обращаемся к этому напрямую, другие проблемы поднимают их озорные головы, как в игре с окисленным, но безопасным умом.

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

1 Ответ

0 голосов
/ 25 ноября 2018

Существуют различные решения этой задачи.Можно было бы передать результат как выходной параметр функции:

fn iter_els<'el>(el_top: &'el El, result: &mut Vec<&'el El>) {
    result.push(el_top);
    for el in &el_top.children {
        iter_els(el, result);
    }
}

fn main() {
    // build top_el as you did
    let mut result = Vec::new();
    iter_els(&top_el, &mut result);
    println!("{:?}", result);
}

Адаптация вашего исходного подхода imho приводит к более сложной реализации:

fn iter_els<'el>(prev_result: &Vec<&'el El>) -> Vec<&'el El> {
    // Iterate over all elements from a tree, starting at the top-level element.
    let mut result = prev_result.clone();

    for el in prev_result {
        for child in &el.children {
            result.push(&child);
        }
        result.extend(iter_els(&el.children.iter().collect()));
    }
    result
}

fn main() {
    // build top_el as you did
    println!("{:?}", iter_els(&vec![&top_el]));
}

В качестве альтернативы:

fn iter_els<'el>(prev_result: &'el Vec<El>) -> Vec<&'el El> {
    // Iterate over all elements from a tree, starting at the top-level element.
    let mut result : Vec<_> = prev_result.iter().collect();

    for el in prev_result {
        for child in &el.children {
            result.push(child);
        }
        result.extend(iter_els(&el.children));
    }
    result
}

fn main() {
    // build top_el as you did
    println!("{:?}", iter_els(&vec![top_el]));
}

Как видите, первый подход работает только с неизменным El и одним единственным результатом Vec, в то время как другие реализации не обходят clone и collect.

В идеале, вы бы написали пользовательский Iterator для своего дерева, но я думаю, что это может быть довольно громоздким, потому что этот итератор должен как-то отслеживать текущее состояние (возможно, может доказать, что я ошибаюсь, и показать, что этона самом деле это легко сделать).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...