rust实现std::promise
时间: 2023-10-23 22:13:08 浏览: 144
Rust没有内置的std :: promise类,但是可以使用Rust的Future和async / await语法来实现类似的功能。
一个可能的实现如下:
```rust
use std::sync::{Arc, Mutex};
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use std::cell::UnsafeCell;
struct Promise<T> {
state: Arc<Mutex<State<T>>>,
}
impl<T> Promise<T> {
fn new() -> (Self, FuturePromise<T>) {
let state = Arc::new(Mutex::new(State::Pending));
let promise = Promise { state: state.clone() };
let future = FuturePromise { state };
(promise, future)
}
fn set_value(&self, value: T) {
let mut state = self.state.lock().unwrap();
match *state {
State::Pending => {
*state = State::Resolved(value);
}
_ => panic!("Promise already resolved"),
}
}
fn set_error(&self, error: String) {
let mut state = self.state.lock().unwrap();
match *state {
State::Pending => {
*state = State::Rejected(error);
}
_ => panic!("Promise already resolved"),
}
}
}
enum State<T> {
Pending,
Resolved(T),
Rejected(String),
}
struct FuturePromise<T> {
state: Arc<Mutex<State<T>>>,
}
impl<T> Future for FuturePromise<T> {
type Output = Result<T, String>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut state = self.state.lock().unwrap();
match &mut *state {
State::Pending => Poll::Pending,
State::Resolved(value) => {
let value = std::mem::replace(value, unsafe { std::mem::uninitialized() });
Poll::Ready(Ok(value))
}
State::Rejected(error) => {
let error = std::mem::replace(error, unsafe { std::mem::uninitialized() });
Poll::Ready(Err(error))
}
}
}
}
unsafe impl<T> Send for Promise<T> {}
unsafe impl<T> Sync for Promise<T> {}
unsafe impl<T> Send for FuturePromise<T> {}
unsafe impl<T> Sync for FuturePromise<T> {}
fn main() {
let (promise, future) = Promise::new();
let handle = std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_secs(1));
promise.set_value(42);
});
let result = futures::executor::block_on(future);
handle.join().unwrap();
println!("{:?}", result);
}
```
这个实现使用了Arc,Mutex和UnsafeCell来实现线程安全的状态共享。FuturePromise实现了Future trait,它持有一个Mutex来保护状态。在poll方法中,它首先获取Mutex的锁,然后检查状态是否已经解决。如果状态是Pending,则返回Pending,否则返回Ready结果,同时从状态中提取值或错误。Promise实现了set_value和set_error方法,它们分别将状态设置为Resolved或Rejected状态,并在状态已经解决时抛出错误。在main函数中,我们创建一个Promise和FuturePromise对,并使用线程来解决Promise。最后,我们使用futures :: executor :: block_on函数等待FuturePromise结果,并打印它。
阅读全文