gpt4 book ai didi

rust - 如何在 Rust 中实现基于生成器或异步函数的轻量级长生命周期线程?

转载 作者:行者123 更新时间:2023-11-29 08:13:32 24 4
gpt4 key购买 nike

我想以用 Rust 编写的轻量级、长生命周期线程的形式实现用户交互脚本。在脚本中,我有异步等待用户输入的位置。

在 JavaScript 中,我会使用一个生成器,您可以在其中传递问题并返回答案,例如:

function* my_scenario() {
yield "What is your name?";
let my_name = yield "How are you feeling?";
let my_mood = yield "";
...
}

let my_session = my_scenario();
...
my_session.next("Peter");
my_session.next("happy");

但是,Rust 的生成器方法 resume() 不包含任何参数!我不能克隆一个生成器或从一个函数中返回它来让许多用户 session 具有不同的状态。我没有使用生成器,而是考虑使用 async fn(),但我不明白如何在每一步调用它,将值传递到那里。

最佳答案

yield 的返回值实际上只是隐式传递给第一个生成器的另一个生成器,只是它强制将两者以奇怪的方式绑定(bind)在一起。

您可以在原始代码中通过垃圾 yield "" 看到,即使您没有任何返回值,您也需要它来获取值。此外,您的示例要求生成器的用户在问题被问到之前就知道问题的答案,这看起来很不正统。

显式传入第二个生成器:

#![feature(generators, generator_trait)]

use std::{
io,
ops::{Generator, GeneratorState},
};

fn user_input() -> impl Generator<Yield = String> {
|| {
let input = io::stdin();
loop {
let mut line = String::new();
input.read_line(&mut line).unwrap();
yield line;
}
}
}

fn my_scenario(
input: impl Generator<Yield = String>,
) -> impl Generator<Yield = &'static str, Return = String> {
|| {
let mut input = Box::pin(input);

yield "What is your name?";
let my_name = match input.as_mut().resume(()) {
GeneratorState::Yielded(v) => v,
GeneratorState::Complete(_) => panic!("input did not return a value"),
};

yield "How are you feeling?";
let my_mood = match input.as_mut().resume(()) {
GeneratorState::Yielded(v) => v,
GeneratorState::Complete(_) => panic!("input did not return a value"),
};

format!("{} is {}", my_name.trim(), my_mood.trim())
}
}

fn main() {
let my_session = my_scenario(user_input());
let mut my_session = Box::pin(my_session);

loop {
match my_session.as_mut().resume(()) {
GeneratorState::Yielded(prompt) => {
println!("{}", prompt);
}
GeneratorState::Complete(v) => {
println!("{}", v);
break;
}
}
}
}
$ cargo run
What is your name?
Shep
How are you feeling?
OK
Shep is OK

您也可以提供硬编码数据:

let user_input = || {
yield "Peter".to_string();
yield "happy".to_string();
};

let my_session = my_scenario(user_input);

关于rust - 如何在 Rust 中实现基于生成器或异步函数的轻量级长生命周期线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56415904/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com