Генератор, похоже, не предоставляет метод `resume()`

Я смотрел на генераторы в Rust и решил попробовать. Я реализовал самый простой пример, который смог найти:

#![feature(generators, generator_trait)]

use std::ops::Generator;

fn main() {
    let mut generator = || {
        println!("2");
        yield;
        println!("4");
    };

    println!("1");
    generator.resume();
    println!("3");
    generator.resume();
    println!("5");
}

Однако, когда я пытаюсь скомпилировать, я получаю эту ошибку:

error[E0599]: no method named `resume` found for type `[generator@src/main.rs:6:25: 10:6 _]` in the current scope
  --> src/main.rs:13:15
   |
13 |     generator.resume();
   |               ^^^^^^

Я что-то делаю не так или метода resume() на самом деле не существует на генераторах? Если да, то как я могу разбудить генератор? В документации я смог найти все, что указывает на метод resume(), поэтому я сейчас запутался.

Примечание: Да, я знаю, что это нестабильная функция языка, но в документе она побуждает пользователей попробовать и использовать ее, поэтому я предполагаю, что она должна быть хотя бы частично реализована?

Моя текущая среда: rustc 1.35.0-nightly (acd8dd6a5 2019-04-05)

ваша собственная ссылка показывает вам ответ

Stargateur 08.04.2019 18:15

Ну, я, должно быть, ослеп! Извините за потраченное время!

Matteo Monti 08.04.2019 18:16

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

Stargateur 08.04.2019 18:18
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
0
3
96
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Yes, I am aware that this is an unstable feature

Нестабильные функции имеют тенденцию меняться со временем, и это так. С недавней стабилизацией Pin подпись resume была изменена (ПР № 55704)

fn resume(self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return>;

Но к счастью в примерах есть еще и был принят.

Итак, ваш код должен выглядеть так:

#![feature(generators, generator_trait)]

use std::ops::Generator;
use std::pin::Pin;

fn main() {
    let mut generator = || {
        println!("2");
        yield;
        println!("4");
    };

    let mut pin = Pin::new(&mut generator);
    println!("1");
    pin.as_mut().resume();
    println!("3");
    pin.as_mut().resume();
    println!("5");
}

Положительным моментом этого является то, что этот подход больше не нуждается в unsafe (который отсутствует в вашем коде и, следовательно, не должен компилироваться на более старой ночной версии), и поэтому для генератора был выбран Pin API.

Извлеченные уроки: если вы используете ночной компилятор, также используйте ночной док.

новый API выглядит не очень удобным для пользователя.

Stargateur 08.04.2019 18:13

Чтобы быть ближе к исходному коду, вы можете опустить проверку состояния: Pin::new(&mut generator).resume();

Jmb 09.04.2019 09:23

@Stargateur лучше?

hellow 09.04.2019 09:28

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

Shepmaster 10.04.2019 17:10

Другие вопросы по теме