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 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题