go - 在非本地包中扩展接口(interface)方法

标签 go interface network-programming microservices

尝试在 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/

相关文章:

go - 在golang中发出post请求

go - "go get"如何知道远程 repo 要使用什么版本控制系统?

java - 接口(interface)对象和类对象的区别

c++ - 如何通过本地 LAN 使用网络别名自动访问嵌入式设备的 Web 服务器?

java - 客户端-服务器中的 JmDNS 服务发现

validation - Go-Validator如何检查字段的零值?

go - 如何读取 Go 中的嵌入式字段?

json - 读取 map[string]interface{} 中的数据

Java - 为什么我的鼠标不能正确移动?

sockets - 带多宿主的 SCTP 作为 TCP 的直接替代