我有一个通用处理程序,其中包含执行所有操作所需的数据。
type Handler struct {
info HandlerInfo
}
然后是发件人结构,它同样具有自己的信息。
type Sender struct {
info SenderInfo
}
最后,有一个接收器,它也有自己的信息。
type Receiver struct {
info ReceiverInfo
}
处理程序会在程序执行期间生成通信对。我不想举例说明我定义的不同结构之间发生的通信类型,因为我希望示例尽可能广泛。
func (h Handler) Do() {
for /* something happens */ {
sender := Sender{}
receiver := Receiver{}
}
sender.DoSomething()
if sender.ShouldSend() {
receiver.Receive()
}
}
到目前为止,一切看起来都很简单,但是我面临两个问题:
1)如何处理发送方和接收方共享的数据而没有冗余?
2)如何处理Handler使用的数据,但发件人和接收者也需要使用这些数据?
有人可能会说,只需要用它们需要的东西逐步填充两个结构
但是这会使IMO变得多余很多。
func DoSomethingAndFill() {
data1 := generateSomeData1()
recv.Receive1(data1)
sender.Send1(data1)
data2 := generateSomeData2()
recv.Receive2(data2)
sender.Send2(data2)
}
我告诉自己,我可以(偶尔地)共享一个基本结构,其中包含需要共享的数据:
type MetaData struct {
Data1 Data
Data2 Data
}
type Sender struct {
*MetaData
info SenderInfo
}
type Receiver struct {
*MetaData
info ReceiverInfo
}
初始化时,我只需要放置相同的指针?
func init() {
md := MetaData{}
recv, send := Receiver{&md}, Sender{&md}
}
但这迫使我要做两件事:
一方面,如果我想使环境整洁并为Receiver制作一个程序包,为Sender制作一个程序包,则我必须将导出的MetaData的所有字段(虽然不是很糟糕)但并不理想。
另一方面,我不得不使代码更加混乱,因为在填充结构时,我不得不在发送者,接收者和元数据之间进行权衡。
我想到的第一件事是对父结构进行某种反向链接:
type Handler struct {
Info HandlerInfo
}
type Sender struct {
handler Handler
info SenderInfo
}
type Receiver struct {
handler Handler
info ReceiverInfo
}
func (h Handler) MakeRecvAndSend() {
recv, send := Receiver{
handler: h,
}, Sender{
handler: h,
}
}
乍一看似乎还不错,但是如果Sender和Receiver放在不同的程序包中,并且由于Golang中不允许循环导入,则不可能。
我想到的另一种解决方案是逐段复制相关信息:
type Handler struct {
info1 HandlerInfo
info2 HandlerInfo
}
type Sender struct {
handlerInfo HandlerInfo
info SenderInfo
}
type Receiver struct {
handlerInfo HanlderInfo
info ReceiverInfo
}
func (h Handler) MakeRecvAndSend() {
recv, send := Receiver{
handlerInfo: h.info1,
}, Sender{
handler: h.info2,
}
}
但这确实很冗长,根据我生成发送方和接收方的方式,我担心这会影响运行时速度/内存。
如果您已经遇到此类问题,请您提供反馈以及解决问题的方式。您可能想分享的任何理论思想也使我很有趣!
谢谢!