I'm trying to share an Arc<Mutex<T>> with a closure. I get the error that closure is FnOncebecause it moves the variableshared_wake_deque_ out of its environment:
use core::task::{Context, Poll, Waker}; use hyper::client::connect::{Connection, Connected}; use std::sync::{Arc, Mutex}; use std::collections::VecDeque; pub type OnPollRead = Arc<dyn Fn(&mut Context<'_>, &mut tokio::io::ReadBuf<'_>) -> Poll<std::io::Result<()>> + Send + Sync>; pub type OnPollWrite = Arc<dyn Fn(&mut Context<'_>, &[u8]) -> Poll<core::result::Result<usize, std::io::Error>> + Send + Sync>; #[derive(Clone)] pub struct CustomTransporter { on_poll_read: Option<OnPollRead>, on_poll_write: Option<OnPollWrite>, } pub struct OVPNClient { } impl OVPNClient { pub fn send(&self, buffer: &[u8]) { } } unsafe impl Send for OVPNClient {} unsafe impl Send for CustomTransporter {} impl CustomTransporter { pub fn new(on_poll_read: Option<OnPollRead>, on_poll_write: Option<OnPollWrite>) -> CustomTransporter { CustomTransporter{ on_poll_read: on_poll_read, on_poll_write: on_poll_write } } } fn main () { let openvpn_client = Arc::new(Mutex::new(OVPNClient{})); let shared_wake_deque = Arc::new(Mutex::new(VecDeque::<Waker>::new())); let shared_wake_deque_ = shared_wake_deque.clone(); let on_poll_read = Arc::new(|context: &mut Context, buffer: &mut tokio::io::ReadBuf| -> Poll<std::io::Result<()>> { let shared_wake_deque__ = shared_wake_deque_; Poll::Ready(Ok(())) }); let on_poll_write = Arc::new(|context: &mut Context, buffer: &[u8]| -> Poll<core::result::Result<usize, std::io::Error>>{ openvpn_client.lock().unwrap().send(buffer); Poll::Ready(Ok(0)) }); let connector = CustomTransporter::new(Some(on_poll_read), Some(on_poll_write)); } Error:
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` --> src/main.rs:44:33 | 44 | let on_poll_read = Arc::new(|context: &mut Context, buffer: &mut tokio::io::ReadBuf| -> Poll<std::io::Result<()>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this closure implements `FnOnce`, not `Fn` 45 | let shared_wake_deque__ = shared_wake_deque_; | ------------------ closure is `FnOnce` because it moves the variable `shared_wake_deque_` out of its environment ... 54 | let connector = CustomTransporter::new(Some(on_poll_read), Some(on_poll_write)); | ------------ the requirement to implement `Fn` derives from here I get that moving can only occur one time. I didn't even made the closure move. As you see, I'm trying to use a clone of the Arc<Mutex<T>> so I'm not exactly moving it. You can see that I tried cloning so I move a variable that is used just on this closure and never anymore, but it didn't work.
没有评论:
发表评论