douhui1333 2018-04-23 05:02
浏览 56
已采纳

在非本地包中扩展接口方法

Trying to create a microservice within Go, I have a package network to take care of getting the bytes and converting to a particular request:

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
}}

Now in the main, I want to handle the request.

package main
import (
    "network"
)

(ra *RequestA) Handle() {
// handle here
}

(rb *RequestB) Handle() {
// handle
}

func main() {
    // get conn here
    req = GetRequestFromBytes(conn)
    req.Handle()
}

However, Golang does not allow RequestA/RequestB classes to be extended in the main package. Two solutions I found online were type aliasing/embedding, but in both it looks like we'll have to handle by finding the specific type of the request at runtime. This necessitates a switch/if statement in both network and main packages, which duplicates code in both.

The simplest solution would be to move the switch statement into package main, where we determine the type of the request and then handle it, but then package main would have to deal with raw bytes, which I'd like to avoid. The responsibility of finding the request type and sending it 'upwards' should rest with the network package.

Is there a simple idiomatic Go way to solve this?

  • 写回答

2条回答 默认 最新

  • dongmin3754 2018-04-23 05:09
    关注

    Use a type switch in the main package:

    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
    }
    

    This avoids encoding knowledge of the protocol bytes in the main package.

    Because the question specifies that parsing code is in the network package and handler code is in the main package, it's not possible to avoid updating the code in two packages when a new request type is added. Even if the language supported the feature proposed in the question, it would still be necessary to update two packages when a new request type is added.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示