尝试在 Go 中创建微服务,我有一个包网络来处理获取字节并转换为特定请求:
package network
type Request interface {
}
type RequestA struct {
a int
}
type RequestB struct {
b string
}
func GetRequestFromBytes(conn net.Conn) Request {
buf := make([]byte, 100)
_, _ := conn.Read(buf)
switch buf[0] {
case 0:
// convert bytes into RequestA
requestA = RequestAFromBytes(buf[1:])
return requestA
case 1:
requestB = RequestBFromBytes(buf[1:])
return requestB
}}
现在主要是我要处理请求。
package main
import (
"network"
)
(ra *RequestA) Handle() {
// handle here
}
(rb *RequestB) Handle() {
// handle
}
func main() {
// get conn here
req = GetRequestFromBytes(conn)
req.Handle()
}
但是,Golang不允许在主包中扩展RequestA/RequestB类。我在网上找到的两个解决方案是类型别名/嵌入,但在这两种解决方案中,我们似乎都必须通过在运行时查找请求的特定类型来处理。这需要在 network 和 main 包中都有一个 switch/if 语句,这会在两个包中重复代码。
最简单的解决方案是将 switch 语句移动到 package main 中,我们在其中确定请求的类型然后处理它,但是 package main 必须处理原始字节,我想避免这种情况。查找请求类型并将其“向上”发送的责任应由网络包承担。
是否有一种简单的惯用 Go 方法来解决这个问题?
最佳答案
使用 type switch在主包中:
switch req := network.GetRequestFromBytes(conn).(type) {
case *network.RequestA:
// handle here, req has type *RequestA in this branch
case *network.RequestB:
// handle here, req has type *RequestB in this branch
default:
// handle unknown request type
}
这避免了对主包中协议(protocol)字节的编码知识。
因为问题指定解析代码在网络包中,处理程序代码在主包中,所以在添加新请求类型时无法避免更新两个包中的代码。即使语言支持问题中提出的功能,在添加新请求类型时仍然需要更新两个包。
关于go - 在非本地包中扩展接口(interface)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49973699/