在地图golang

时间:2018-11-08 08:43:28

标签: go

有什么方法可以将地图创建为多个结构,然后使用它?

我有几种不同的结构,它们实现相同的接口并为每个结构匹配输入类型。

我想从不同的输入中读取数据到结构中-在编译时不知道输入类型。

type myInput struct {
    InputType  string
    data       []bytes
}

// Will get as an input after compeleation
inputs := []myInput{
    myInput{InputType: "a", data: []bytes{0x01, 0x02, 0x03}},
    myInput{InputType: "b", data: []bytes{0x01, 0x02}},
}

type StructA struct {
   A uint16
   B uint32
}

func (a StructA) name () {
    fmt.Printf("name is: %d %d", a.A, a.B)
}

type StructB struct {
   C uint32
}

func (b StructB) name () {
    fmt.Printf("name is: %d", b.C)
}

AorB map[string]<???> {
    "a": StructA,
    "b": StructB,
}

在这一点上,我不知道该怎么办。我需要通过输入类型获取正确的结构,并使用binary.Read初始化结构。

for _, myInput := range (inputs) {
    // ???? :(
    myStruct := AtoB[myInput.InputType]{}
    reader :=bytes.NewReader(input1)
    err := binary.Read(reader, binary.BigEndian, &myStruct)
    fmt.Printf(myStruct.name())
}

谢谢!

3 个答案:

答案 0 :(得分:1)

定义接口

type Bin interface {
    name() string
    set([]byte) // maybe returning error
}

您将仅处理Bin

type StructA struct { /* your code so far */ }
type StructB struct { /* your code so far */ }

func (a *StructA) set(b []byte) {
    a.A = b[0]<<8 + b[1] // get that right, too lazy to code this for you
    a.B = b[2]<<24 + b[3]<<16 + ...  
}
// same for StructB

所以您的StructA / B现在是Bins。

func makeBin(in myInput) Bin {
     var bin Bin
     if in.InputType == "a" {
         bin = &StructA{}
     } else {
         bin = &StructB{}
     }
     bin.set(in.data) // error handling?
     return bin
}

如果您有两种以上类型:如果使用if,请改用开关,或者使用小型注册表(反射)。

答案 1 :(得分:1)

首先,您为常用的interface func定义一个name

type Namer interface {
    name()
}

然后,您可以创建到该接口的映射并插入结构:

AorB := map[string] Namer {
    "a": StructA{
        A: 42,
        B: 28,
    },
    "b": StructB{
        C: 12,
    },
}

现在您可以访问所有条目:

for _, n := range AorB {
    n.name()
} 

答案 2 :(得分:-2)

您可以使用相同的界面

AorB := map[string]interface{}{
    "a": StructA{},
    "b": StructB{},
} 

当您取回值时,可以将A类型声明为A,将B类型声明为B