Рекурсивный генератор в Русте - PullRequest
1 голос
/ 12 октября 2019

Я пытаюсь портировать этот генератор простых чисел python на ржавчину с помощью генераторов ржавчины и этой оболочки генератора от итератора .

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

error[E0720]: opaque type expands to a recursive type
  --> src/main.rs:27:29
   |
27 | fn recursive_generator() -> impl Iterator<Item = u64> {
   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^ expands to a recursive type
   |
   = note: expanded type is `GeneratorToIterator<[generator@src/main.rs:28:25: 
   48:6 {u64, (), impl std::iter::Iterator}]>`

Ниже приведена реализация рекурсивного генератора, выдающего эту ошибку:


fn recursive_generator() -> impl Iterator<Item = u64> {
    GeneratorToIterator(move || {
        // Yield a few values
        yield 1;
        yield 2;
        yield 3;

        // Initialize the inner generator
        let mut inner_value: u64 = 0;
        let mut inner_generator = recursive_generator();

        // Get the first value of the inner generator
        match inner_generator.next(){
             Some(x) => inner_value += x,
             None => {},
        }

        // Yield some other values
        yield 4;
        yield 5;
        yield 6;
    })
}

Полная реализация (с определением GeneratorToIterator) может быть найдена здесь .

Я нашел этот связанный вопрос но яне удалось скомпилировать их gen_to_iter функцию.

РЕДАКТИРОВАТЬ: Благодаря ответу @bluss я наконец-то смог реализовать рабочую версию генератора простых чисел в ржавчине.

1 Ответ

1 голос
/ 12 октября 2019

В объяснении об ошибке E0720 упоминается, что тип impl Trait должен расширяться до типа, который не содержит других типов impl Trait, но здесь тип, конечно, рекурсивный, поскольку в этом суть.

Это можно обойти, используя вместо этого объекты в штучной упаковке - Box<Iterator<Item=u64>> здесь хорошо работает и позволяет избежать проблемы.

Либо отрегулируйте recursive_generator, чтобы вернуть Box<Iterator<Item=u64>>, либо измените строкурекурсивный вызов для использования упакованного итератора только для этого рекурсивного случая.

...