Дополнительные методы для рекурсивных шаблонов в итерации - PullRequest
0 голосов
/ 11 июля 2020

Основывается на Приёмах превращения рекурсивных функций в итераторы в Rust? , я хотел бы изучить проблемы итераторов.

Давайте подумаем о рекурсивной функции на основе доходности более сложный поток управления:

function one_level(state, depth, max_depth) {
  if depth == max_depth {
    return
  }
  if external_condition(state) {                 // location-1
     for s in next_states_from(state) {          // loop-1
       yield state_to_value(s);
       yield one_level(s, depth+1, max_depth); 
     }
  } else {
     for s in other_next_state_from(state) {     // loop-2
       yield one_level(s, depth+1, max_depth)    // location-2
     }
  }
}

Здесь все становится интересно, потому что есть:

  • условные переходы
  • несколько точек рекурсии

Управляя всем этим с помощью итератора Rust, я обнаружил, что в основном украшаю свой объект состояния такими свойствами, как location_1_reached:bool, чтобы я мог установить их в своей функции next() перед возвратом. Затем мне нужно засорить свой код проверками, чтобы увидеть, как далеко мы продвинулись в предыдущий раз через состояние этого кадра стека. Опять же, я изо всех сил пытаюсь справиться с этим чисто.

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

struct MyIteratorStackFrame<'a> {
    arg_1: usize,
    arg_2: Point,
    loop_1_values: Box<dyn Iterator<Item = &'a State> + 'a>,
    loop_2_values: Box<dyn Iterator<Item = &'a State> + 'a>,
    location_1_reached: bool,
    location_2_reached: bool
}

struct MyIterator<'a> {
    max_depth: usize,
    stack: Vec<MyIteratorStackFrame<'a>>,
}

1 Ответ

1 голос
/ 11 июля 2020

Паттерн, о котором вы говорите, является «конечным автоматом», и его лучше всего представить в Rust с помощью перечисления:

enum Frame {
    NextStates(NextStatesIterator, State),
    OtherStates(OtherStatesIterator)
}
struct Iterator {
    stack: Vec<Frame>, 
}
...