-1

我想用一个容器来管理tokio::oneshot::Senders。我正在使用Vec,但似乎保存的值Vec是引用,我需要使用self,而不是引用来调用它:

use bytes::BytesMut;
use tokio::sync::oneshot;

#[derive(Clone)]
pub enum ChannelData {
    Video { timestamp: u32, data: BytesMut },
    Audio { timestamp: u32, data: BytesMut },
    MetaData {},
}

pub type PlayerPublisher = oneshot::Sender<ChannelData>;

pub struct Channel {
    player_producers: Vec<PlayerPublisher>, // consumers who subscribe this channel.
}

impl Channel {
    fn new() -> Self {
        Self {
            player_producers: Vec::new(),
        }
    }

    async fn transmit(&mut self) {
        let b = BytesMut::new();
        let data = ChannelData::Video {
            timestamp: 234,
            data: b,
        };

        for i in self.player_producers {
            i.send(data);
        }
    }
}

错误:

error[E0507]: cannot move out of `self.player_producers` which is behind a mutable reference
  --> src/lib.rs:31:18
   |
31 |         for i in self.player_producers {
   |                  ^^^^^^^^^^^^^^^^^^^^^
   |                  |
   |                  move occurs because `self.player_producers` has type `Vec<tokio::sync::oneshot::Sender<ChannelData>>`, which does not implement the `Copy` trait
   |                  help: consider iterating over a slice of the `Vec<_>`'s content: `&self.player_producers`

error[E0382]: use of moved value: `data`
  --> src/lib.rs:32:20
   |
26 |         let data = ChannelData::Video {
   |             ---- move occurs because `data` has type `ChannelData`, which does not implement the `Copy` trait
...
32 |             i.send(data);
   |                    ^^^^ value moved here, in previous iteration of loop

我怎样才能实现我的目标?

pub fn send(mut self, t: T) -> Result<(), T> {
    let inner = self.inner.take().unwrap();

    inner.value.with_mut(|ptr| unsafe {
        *ptr = Some(t);
    });

    if !inner.complete() {
        unsafe {
            return Err(inner.consume_value().unwrap());
        }
    }

    Ok(())
}
4

2 回答 2

0

调用send需要拥有 oneshot 通道的所有权。要获得该所有权,您可以取得容器的所有权。在这种情况下,最简单的方法是获取以下内容的所有权Channel

async fn transmit(self) { // Changed to `self`
    for i in self.player_producers {
        let data = ChannelData::Video {
            timestamp: 234,
            data: BytesMut::new(),
        };
        if i.send(data).is_err() {
            panic!("Unable to send data");
        }
    }
}

其他选项是drain集合:

for i in self.player_producers.drain(..) {

或者用一个空的集合交换

use std::mem;
for i in mem::take(&mut self.player_producers) {

在每种情况下,data每次发送时都必须构造(或克隆)有效负载。

也可以看看:

于 2021-04-05T17:11:06.460 回答
0

Tokio oneshot 发件人只能发送一条消息,因此send将使用Sender. send要从a中调用Vec,您首先必须将其删除&mut Vec在迭代它们时删除所有元素的方法是drain

for i in self.player_producers.drain(..) {
    i.send(data);
}

您的另一个错误是data调用send. 由于您想将相同的数据发送给多个发件人,因此您必须这样clone做:

i.send(data.clone());

请注意send返回 a的警告Result

于 2021-04-05T17:12:16.127 回答