英文:
tokio::sync::broadcast::Receiver<T> is not Clone
问题
我有一个像这样的结构体:
#[derive(Clone)]
struct Foo {
... // 其他状态
receiver: tokio::sync::watch::Receiver<T>,
}
但是我意识到,为了应用程序的目的,我实际上需要一个tokio::sync::broadcast
通道,它本身只在Sender
半部分实现了Clone
,而不是Receiver
。所以我不能简单地将Receiver
替换为Clone
,因为无法派生Clone
。也许手动实现Clone
是答案,但我不确定它会是什么样子。我认为它需要一个对发送方的处理和一个对sender.subscriber()
的调用。我不确定这是否是正确的方法。
如果通道类型更改为广播,我如何拥有一个类型为Foo
的类型,我可以克隆句柄,其中每个句柄都能等待接收新消息?
英文:
I have a struct like this:
#[derive(Clone)]
struct Foo {
... // other state
receiver: tokio::sync::watch::Receiver<T>,
}
But I realize for purposes of the application I actually need a tokio::sync::broadcast
channel, which itself only implements Clone
in the Sender
half, not the Receiver
. So I can't simply make a drop-in replacement for the receiver as Clone
can't be derived. Maybe a manual Clone
implementation is the answer, but I'm not sure what that would look like. It requires a handle to the sender and a call to sender.subscriber()
I believe. Not sure this is the right approach.
How can I have a type Foo
which I can clone handles to where each one is capable of awaiting to receive a new message, if the channel type changes to broadcast?
答案1
得分: 2
在tokio::sync::broadcast
中,通过调用Sender
上的subscribe方法来创建接收者,就像模块文档所述:
> 调用Sender::subscribe
可以创建新的Receiver
句柄。返回的Receiver
将接收在调用subscribe
之后发送的值。
但是,您还可以通过在其上调用resubscribe来创建新的Receiver
。这将:
> 从当前尾部元素重新订阅通道。
>
> 此接收者句柄将接收到在重新订阅之后发送的所有值的克隆。这不包括在当前接收者的队列中的元素。
当然,此方法仅适用于T: Clone
。
因此,如果要使您的Foo
可克隆(并且愿意接受Receiver
文档中提到的限制),您必须手动实现它:
struct Foo<T> {
... // 其他状态
receiver: tokio::sync::watch::Receiver<T>,
}
impl<T: Clone> Clone for Foo<T> {
fn clone(&self) -> Self {
Self {
... // 克隆其他状态
receiver: self.receiver.resubscribe(),
}
}
}
英文:
Receivers in tokio::sync::broadcast
are created by calling subscribe method on Sender
as the module documentation says:
> New Receiver
handles are created by calling Sender::subscribe
. The returned Receiver
will receive values sent after the call to subscribe
.
However you can also create new Receiver
by calling resubscribe on it. Which will:
> Re-subscribes to the channel starting from the current tail element.
>
> This Receiver handle will receive a clone of all values sent after it has resubscribed. This will not include elements that are in the queue of the current receiver.
And this method is of course only available for T: Clone
.
So if you want your Foo
to be Clone
(and you are willing to accept limitations mentioned in the Receiver
documentation), you have to implement it manually:
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(),
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论