我是Go的新手,现在我不确定如何解决。我正在研究一些以原始字节为单位的DNS数据包并返回一个称为DNSPacket的结构的代码。

该结构如下所示

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的类型,必须对Data字段进行不同的解码。例如,如果答案是A记录(类型1),则数据只是一个ipv4地址。但是,如果答案是SRV记录(类型33),则数据包含在 byte slice 中编码的portpriorityweighttarget

我认为,如果我可以在Answer上有一个称为DecodeData()的方法,该方法可以根据类型返回正确的数据,那就太好了,但是由于Go中没有重写或继承,所以我不确定如何解决这个问题。我尝试使用接口(interface)来解决此问题,但无法编译。我尝试了类似的东西
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
 }

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

谢谢!

最佳答案

让我总结一下您的问题。

您有一个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
}

回答
让我们创建一个应该实现以处理数据的接口(interface)。
type PacketProcessor interface {
    Process(Answer)
}

让SRV实现PacketProcessor
type 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)
}

希望能帮助到你 :)。
有一个基于古尔冈的golang社区,随时准备帮助开发人员解决他们的问题。
您可以通过slack加入社区

关于go - Golang正确使用接口(interface),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53862574/

10-16 22:30