Golang接口的正确使用

我是 Go 的新手,遇到了不确定如何解决的情况。我正在编写一些代码,这些代码以原始字节形式获取 DNS 数据包并返回一个名为 DNSPacket 的结构。


该结构如下所示


type DNSPacket struct {

    ...some fields

    Questions  []Question

    Answers    []Answer

    ...some more fields

}

我遇到的问题是 Answers 类型,看起来像这样。


 type Answer struct {

    Name     string

    Type     int

    Class    int

    TTL      uint32

    RdLength int

    Data     []byte

}

根据 Answer 的类型,Data必须对字段进行不同的解码。例如,如果答案是一条A记录(类型 1),则数据只是一个 ipv4 地址。但是,如果 Answer 是SRV记录(类型 33),则数据包含port, priority,weight并target在字节切片中编码。


我认为如果我可以在 Answer 上调用一个方法,根据类型返回正确的数据,那会很棒,DecodeData()但是由于 Go 中没有覆盖或继承,我不确定如何解决这个问题。我尝试使用接口来解决这个问题,但它无法编译。我试过类似的东西


type DNSRecordType interface {

    Decode(data []byte)

}



type RecordTypeSRV struct {

   target string

   ...more fields

}

//to 'implement' the DNSRecordType interface

func (record *RecordTypeSRV) Decode(data []byte) {

    //do the work to decode appropriately and set

    //the fields on the record

}

然后在 Answer 方法中


func (a *Answer) DecodeData() DNSRecordType {

    if a.Type === SRVType {

       record := RecordTypeSRV{}

       record.Decode(a.Data)

       return record

    }


    //do something similar for other record types

 }

具有单一 Answer 类型但能够根据其类型返回不同类型的 Answer Data 的正确 Go 方法是什么?抱歉,如果这是一个完全初学者的问题,因为我对 Go 还是很陌生。


呼啦一阵风
浏览 118回答 2
2回答

胡子哥哥

让我总结一下你的问题。您有一个包含答案列表的 DNS 数据包。根据答案的类型,您必须处理答案中的数据。type DNSPacket struct {    ...some fields    Questions  []Question    Answers    []Answer    ...some more fields}type Answer struct {    Name     string    Type     int    Class    int    TTL      uint32    RdLength int    Data     []byte}Answer 让我们创建一个应该实现的接口来处理数据。type PacketProcessor interface {    Process(Answer)}让 SRV 实现 PacketProcessortype SRV struct {    ...}func (s *SRV) Process(a Answer) {    ...}你的处理逻辑应该如下func (a *Answer) Process() {    var p PacketProcessor    switch a.Type {        case SRVType:        p = &SRV{}        ...        //other cases    }    //finally    p.Process(*a)}

POPMUISE

据我所知,要返回不同的类型,返回参数必须是一个接口。所以你可以像这样简单地声明函数:func (a *Answer) DecodeData() (mode modeType, value interface{}) {}mode表示值为 A 记录或 SRV 记录,您可以使用value字段返回任何您想要的内容。函数调用者可以根据模式处理值如果你想让代码更优雅,你可以为每个模式定义不同的值结构。然后调用者可以如下操作:type modeType intconst (    ARecord modeType = 1    SRVRecord modeType = 2)switch mode {    case ARecord:    // do something    case SRVRecord:    // do something} 
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go