我是 Go 语言的新手,我可以使用一些关于如何重构代码的建议。我所要做的就是取决于 Sarama 的成功或错误(Apache Kafka 正在进行中)我需要进一步记录和转发它。到目前为止,我的代码看起来像这样
go func() {
for err := range producer.Errors() {
batchID := err.Msg.Metadata.(ackMeta).batchID # notice the struct here
statusChan := err.Msg.Metadata.(ackMeta).statusChan
statusChan <- false
close(statusChan)
logs.Debug(appName, "Signalled failure on statusChan for batch ", batchID)
logs.Error(appName, "Failed to publish data to analyzer for batchID: ", batchID, err)
}
}()
go func() {
for succ := range producer.Successes() {
batchID := succ.Metadata.(ackMeta).batchID # notice the struct here
statusChan := succ.Metadata.(ackMeta).statusChan
statusChan <- true
close(statusChan)
logs.Debug(appName, "Signalled success on statusChan for batch ", batchID)
logs.Debug(appName, "Successfully published data to analyzer:", succ.Topic, succ.Key, succ.Partition, succ.Offset, succ.Metadata)
}
我认为我可以做得更好,将整个事情包装在一个函数中,但到目前为止,除了使用此处显示的 switch case 之外,我想不出任何其他方法
func checkSuccessOrFailAck(msg interface{}) {
switch msgType := msg.(type) {
case producer.Errors:
batchID := msg.Msg.Metadata.(ackMeta).batchID
statusChan := msg.Msg.Metadata.(ackMeta).statusChan
statusChan <- false
close(statusChan)
logs.Debug(appName, "Signalled failure on statusChan for batch ", batchID)
logs.Error(appName, "Failed to publish data to analyzer for batchID: ", batchID, msg)
case producer.Successes:
batchID := msg.Metadata.(ackMeta).batchID
statusChan := msg.Metadata.(ackMeta).statusChan
statusChan <- true
close(statusChan)
logs.Debug(appName, "Signalled success on statusChan for batch ", batchID)
logs.Debug(appName, "Successfully published data to analyzer:", succ.Topic, succ.Key, succ.Partition, succ.Offset, succ.Metadata)
}
}
消息的类型不同,我从中提取属性的方式也不同。但我对这种方法不满意,因为声明比前一个多。有没有更好的思考方式来写作?
最佳答案
首先,不清楚第二个代码是否有效。由于 Errors()
和 Successes()
返回 channel ,您需要选择
同时读取它们,而不会阻塞任何一个。
由于 succ
和 err
在代码中有不同的类型,我不确定您是否可以比原始示例短得多。 Go 还没有泛型,因此编写将两者统一的代码具有挑战性。如果您真的需要它,我会尝试找到类型相同的最近点——从那一点开始应该更容易统一代码。比如err.Msg
和succ
是同一种类型?
此外,即使 Go 已经有了泛型,也不清楚统一这些泛型是否会成功。 Go 的哲学是一点点代码重复比过于复杂的抽象要好。代码不是理论上最短的代码,但它是明确和清晰的。
关于go - 根据 Go lang 中的类型处理案例的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54803311/