隐藏两个特征共享的关联类型
Hiding associated type shared by two traits
我具有特定消息类型的发送者和接收者的特征。
pub trait Sends {
type Message;
fn send(&self) -> Self::Message;
}
pub trait Receives {
type Message;
fn receive(&mut self, msg: Self::Message);
}
我希望能够使用传递消息的 run()
方法在结构中存储一对兼容的发送方和接收方,即 receiver.receive(sender.send())
.
我的直觉是这个 run()
方法不需要知道消息类型(因为所有出现的消息类型都在内部处理),所以结构及其方法不应该公开消息类型。我认为当您拥有更大的发送者-接收者网络时,跟踪消息类型也变得不切实际。
最好的方法是什么?我 tried it out 和 Any
,这主要是有效的。然而,
- 我在从
Send
实际创建 SendAny
时遇到了困难,接收者也一样。
- 我希望有一种更优雅、更高效的方法,因为这会引入样板代码并且不需要 boxing/unboxing。
这是我目前得到的:
trait SendsAny {
fn send_any(&self) -> Box<dyn Any>;
}
impl<T> SendsAny for T
where
T: Sends,
T::Message: 'static,
{
fn send_any(&self) -> Box<dyn Any> {
Box::new(self.send())
}
}
// Similar for ReceivesAny
struct SendAndReceive {
// These have to have matching Message types
tx: Box<dyn SendsAny>,
rx: Box<dyn ReceivesAny>,
}
impl SendAndReceive {
fn new<M: 'static>(
tx: Box<dyn Sends<Message = M>>,
rx: Box<dyn Receives<Message = M>>,
) -> Self {
// This doesn't work
let tx = tx as Box<dyn SendsAny>;
todo!()
}
fn run(&mut self) {
self.rx.receive_any(self.tx.send_any());
}
}
我不太清楚这是否是您要查找的内容,但您可以使发送方和接收方的 SendAndReceive
通用:
pub trait Sends {
type Message;
fn send(&self) -> Self::Message;
}
pub trait Receives {
type Message;
fn receive(&mut self, msg: Self::Message);
}
struct SendAndReceive<R,S>
where S: Sends, R: Receives<Message=S::Message>
{
// These have to have matching Message types
tx: S,
rx: R,
}
impl<R,S> SendAndReceive<R,S>
where S: Sends, R: Receives<Message=S::Message>
{
fn new(tx: S,rx: R,) -> Self {
Self{tx, rx}
}
fn run(&mut self) {
self.rx.receive(self.tx.send());
}
}
因此,该结构与消息的类型无关,但在 sender/receiver 上是通用的。还要避免整个 Any
机器。
您也可以采用另一种方式,使消息的结构通用:
pub trait Sends {
type Message;
fn send(&self) -> Self::Message;
}
pub trait Receives {
type Message;
fn receive(&mut self, msg: Self::Message);
}
struct SendAndReceive<M> {
// These have to have matching Message types
tx: Box<dyn Sends<Message=M>>,
rx: Box<dyn Receives<Message=M>>,
}
impl<M> SendAndReceive<M> {
fn new(
tx: Box<dyn Sends<Message = M>>,
rx: Box<dyn Receives<Message = M>>,
) -> Self {
Self{tx,rx}
}
fn run(&mut self) {
self.rx.receive(self.tx.send());
}
}
这再次避免了 Any
并且不需要在 sender/receiver 上是通用的,但在消息类型上必须是通用的。
我不知道这两个是否是你要找的,但我没有看到任何其他方法来避免 run
需要特定的 types/traits。
您应该创建将 Sends
和 Receives
绑定在一起的类型,此处 SendAndReceiveInner
。然后使用特征对象 Box<dyn SendAndReceiveAny>
在 SendAndReceive
.
中以类型擦除形式使用它
struct SendAndReceiveInner<R, S>
where
S: Sends,
R: Receives<Message = S::Message>,
{
tx: S,
rx: R,
}
trait SendAndReceiveAny {
fn run(&mut self);
}
impl<R, S> SendAndReceiveAny for SendAndReceiveInner<R, S>
where
S: Sends,
R: Receives<Message = S::Message>,
{
fn run(&mut self) {
self.rx.receive(self.tx.send());
}
}
struct SendAndReceive {
inner: Box<dyn SendAndReceiveAny>,
}
impl SendAndReceive {
fn new<R, S>(tx: S, rx: R) -> Self
where
S: Sends + 'static,
R: Receives<Message = S::Message> + 'static,
{
Self {
inner: Box::new(SendAndReceiveInner{ tx, rx }),
}
}
fn run(&mut self) {
self.inner.run();
}
}
这涉及的拳击要少得多,但仍有一些样板。您可以只在 Box<dyn ...>
形式中使用它,因为此时最外层的 SendAndReceive
没有做太多事情,但是封装和 API 表示取决于 reader。
我具有特定消息类型的发送者和接收者的特征。
pub trait Sends {
type Message;
fn send(&self) -> Self::Message;
}
pub trait Receives {
type Message;
fn receive(&mut self, msg: Self::Message);
}
我希望能够使用传递消息的 run()
方法在结构中存储一对兼容的发送方和接收方,即 receiver.receive(sender.send())
.
我的直觉是这个 run()
方法不需要知道消息类型(因为所有出现的消息类型都在内部处理),所以结构及其方法不应该公开消息类型。我认为当您拥有更大的发送者-接收者网络时,跟踪消息类型也变得不切实际。
最好的方法是什么?我 tried it out 和 Any
,这主要是有效的。然而,
- 我在从
Send
实际创建SendAny
时遇到了困难,接收者也一样。 - 我希望有一种更优雅、更高效的方法,因为这会引入样板代码并且不需要 boxing/unboxing。
这是我目前得到的:
trait SendsAny {
fn send_any(&self) -> Box<dyn Any>;
}
impl<T> SendsAny for T
where
T: Sends,
T::Message: 'static,
{
fn send_any(&self) -> Box<dyn Any> {
Box::new(self.send())
}
}
// Similar for ReceivesAny
struct SendAndReceive {
// These have to have matching Message types
tx: Box<dyn SendsAny>,
rx: Box<dyn ReceivesAny>,
}
impl SendAndReceive {
fn new<M: 'static>(
tx: Box<dyn Sends<Message = M>>,
rx: Box<dyn Receives<Message = M>>,
) -> Self {
// This doesn't work
let tx = tx as Box<dyn SendsAny>;
todo!()
}
fn run(&mut self) {
self.rx.receive_any(self.tx.send_any());
}
}
我不太清楚这是否是您要查找的内容,但您可以使发送方和接收方的 SendAndReceive
通用:
pub trait Sends {
type Message;
fn send(&self) -> Self::Message;
}
pub trait Receives {
type Message;
fn receive(&mut self, msg: Self::Message);
}
struct SendAndReceive<R,S>
where S: Sends, R: Receives<Message=S::Message>
{
// These have to have matching Message types
tx: S,
rx: R,
}
impl<R,S> SendAndReceive<R,S>
where S: Sends, R: Receives<Message=S::Message>
{
fn new(tx: S,rx: R,) -> Self {
Self{tx, rx}
}
fn run(&mut self) {
self.rx.receive(self.tx.send());
}
}
因此,该结构与消息的类型无关,但在 sender/receiver 上是通用的。还要避免整个 Any
机器。
您也可以采用另一种方式,使消息的结构通用:
pub trait Sends {
type Message;
fn send(&self) -> Self::Message;
}
pub trait Receives {
type Message;
fn receive(&mut self, msg: Self::Message);
}
struct SendAndReceive<M> {
// These have to have matching Message types
tx: Box<dyn Sends<Message=M>>,
rx: Box<dyn Receives<Message=M>>,
}
impl<M> SendAndReceive<M> {
fn new(
tx: Box<dyn Sends<Message = M>>,
rx: Box<dyn Receives<Message = M>>,
) -> Self {
Self{tx,rx}
}
fn run(&mut self) {
self.rx.receive(self.tx.send());
}
}
这再次避免了 Any
并且不需要在 sender/receiver 上是通用的,但在消息类型上必须是通用的。
我不知道这两个是否是你要找的,但我没有看到任何其他方法来避免 run
需要特定的 types/traits。
您应该创建将 Sends
和 Receives
绑定在一起的类型,此处 SendAndReceiveInner
。然后使用特征对象 Box<dyn SendAndReceiveAny>
在 SendAndReceive
.
struct SendAndReceiveInner<R, S>
where
S: Sends,
R: Receives<Message = S::Message>,
{
tx: S,
rx: R,
}
trait SendAndReceiveAny {
fn run(&mut self);
}
impl<R, S> SendAndReceiveAny for SendAndReceiveInner<R, S>
where
S: Sends,
R: Receives<Message = S::Message>,
{
fn run(&mut self) {
self.rx.receive(self.tx.send());
}
}
struct SendAndReceive {
inner: Box<dyn SendAndReceiveAny>,
}
impl SendAndReceive {
fn new<R, S>(tx: S, rx: R) -> Self
where
S: Sends + 'static,
R: Receives<Message = S::Message> + 'static,
{
Self {
inner: Box::new(SendAndReceiveInner{ tx, rx }),
}
}
fn run(&mut self) {
self.inner.run();
}
}
这涉及的拳击要少得多,但仍有一些样板。您可以只在 Box<dyn ...>
形式中使用它,因为此时最外层的 SendAndReceive
没有做太多事情,但是封装和 API 表示取决于 reader。