我有一个这样的 struct :

#[derive(Clone)]
struct Foo {
    ...  // other state
    receiver: tokio::sync::watch::Receiver<T>,
}

但我意识到,为了应用程序的目的,我实际上需要一个tokio::sync::broadcast通道,它本身只实现Sender一半中的Clone,而不是Receiver.所以我不能简单地替换接收器,因为Clone不能推导出来.也许手动Clone实现是答案,但我不确定它会是什么样子.我想它需要一个发信人的账号和一个打到sender.subscriber()的电话.不确定这是不是正确的方法.

如果频道类型更改为广播,我如何才能拥有一个类型Foo,我可以将句柄克隆到每个类型都能够等待接收新消息的位置?

推荐答案

tokio::sync::broadcast中的接收器是通过调用Sender上的subscribe方法来创建的,如module documentation所述:

通过呼叫Sender::subscribe创建新的Receiver个句柄.返回的Receiver将接收在调用subscribe之后发送的值.

不过,您也可以通过在上面呼叫resubscribe来创建新的Receiver.这将:

重新订阅从当前尾部元素开始的频道.

此接收方句柄将接收重新订阅后发送的所有值的克隆.这将不包括当前接收方队列中的元素.

当然,这种方法只适用于T: Clone人.

因此,如果您希望FooClone(并且您愿意接受Receiver文档中提到的限制),则必须手动实现它:

struct Foo<T> {
    ...  // other state
    receiver: tokio::sync::watch::Receiver<T>,
}

impl<T: Clone> Clone for Foo {
    fn clone(&self) -> Self {
        Self {
            ... // clone other state
            receiver: self.receiver.resubscribe(),
        }
    }
}

Rust相关问答推荐

什么样的 struct 可以避免使用RefCell?

如何创建引用构造函数拥有的变量的对象?

为什么std repeat trait绑定在impl块和关联函数之间?

制作一片连续整数的惯用Rust 方法?

正则表达式中的重叠匹配?(铁 rust 正则式发动机)

在IntoIter上调用.by_ref().Take().rev()时会发生什么情况

是否可以在不切换到下一个位置的情况下获得迭代器值:

在Rust中,Box:ed struct 与普通 struct 在删除顺序上有区别吗?

在Rust 中移动原始指针的靶子安全吗

如何在 Rust 中显式声明 std::str::Matches<'a, P> ?

实现泛型的 Trait 方法中的文字

在给定 Rust 谓词的情况下,将 Some 转换为 None 的惯用方法是什么?

如何在 Emacs Elisp 中获得类似格式化的 LSP?

在 Bevy 项目中为 TextureAtlas 精灵实施 NearestNeighbor 的正确方法是什么?

如何获取函数中borrow 的切片的第一部分?

预期的整数,找到 `&{integer}`

字符串切片的向量超出范围但原始字符串仍然存在,为什么判断器说有错误?

为什么基于 clap::Parser 读取的大量数字进行计算比硬编码该数字时慢?

类型组的通用枚举

为什么一个整型变量赋值给另一个变量后仍然可以使用?