rust - 如何固定RefCell的内容?

标签 rust rust-tokio

我有一个struct MyAsyncStream 和tokio::io::AsyncWrite实现:

impl<S: AsyncRead + AsyncWrite + Unpin> AsyncWrite for MyAsyncStream<S> {
    fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize>> {
       ....
    }

我也有 MyAsyncStreamWrapper :
struct MyAsyncStreamWrapper{inner: MyAsyncStream}

现在,我想使用以下方法为 MyAsyncStreamWrapper 实现 AnotherTrait 特性:
impl AnotherTrait for MyAsyncStreamWrapper {
    fn poll_send_to<B>(self: Pin<&Self>, cx: &mut Context<'_>, buf: &[u8], addr: B,) -> Poll<Result<usize, Self::Error>> {
        Pin::new(&mut self.inner).poll_write(cx, buf)
    }
    ....
}

在此方法实现中,我想在内部调用poll_write。但是,不幸的是,它们在自我可变性方面有所不同: Pin <&mut Self> Pin <&Self> 。如预期的那样,它不会编译。

对于这种情况,是否有惯用的“解决方法”?我的想法是将内部包装到Mutex中,以便在非可变上下文中可以使用可变的 MyAsyncStream :
MyAsyncStreamWrapper{inner: Mutex<RefCell<MyAsyncStream>>}
...
fn poll_send_to<B>(mut self: Pin<&Self>, cx: &mut Context<'_>, buf: &[u8], addr: B,) -> Poll<Result<usize, Self::Error>> {
       let rc = self.stream.lock().unwrap();
       let ref mut inner  = rc.borrow();
       let pin = Pin::new(inner);

       pin.poll_write(cx, buf);
    }
...


但是,不幸的是,它也无法编译,并出现以下错误:
     pin.poll_write(cx, buf);
         ^^^^^^^^^^ method not found in `std::pin::Pin<&mut std::cell::RefMut<'_, MyAsyncStream>>`


正确的方法是什么?

最佳答案

取消引用然后重新借用似乎有效:

use std::cell::RefCell;
use std::pin::Pin;
use std::sync::Mutex;

fn main() {
    let a = Mutex::new(RefCell::new(42));
    let rc = a.lock().unwrap();
    let mut inner = rc.borrow_mut();
    let pinned = Pin::new(&mut *inner);
    print_type_name(pinned);
}

fn print_type_name<T>(_: T) {
    println!("{}", std::any::type_name::<T>());
}

它输出类型为core::pin::Pin<&mut i32>

话虽这么说,在异步上下文中使用阻塞式同步原语(例如Mutex)可能不是一个好主意。如果可能的话,最好让poll_send_to带有Pin<&mut Self>参数。

关于rust - 如何固定RefCell的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59570046/

相关文章:

rust - 如何将值的所有权从 Rust 转移到 C 代码?

reference - Rust的确切自动引用规则是什么?

rust - Rust tokio_postgres行到对象的映射失败,时间戳列为serde_postgres

rust - 如何在#[no_std] 环境中使用 Tokio Reactor?

rust - 为什么任务超时时不 panic ?

rust - 无法在tokio::fs::File上调用poll_read

file - 如何在 Rust 中异步计算硬盘上文件的校验和?

将 Rc<ConcreteType> 转换为 Rc<Trait>

multithreading - 获取 RwLock 进行读取并使其超出范围

rust - 尝试实现查找或插入时 HashMap 借用问题