Is there any way to create a map into several structs, and then use It?
I have several different structs that implement the same interface and matching input types for each struct.
I want to read data from the different inputs into the structs - without knowing the input type at the compilation time.
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,
}
At this point, I don't know what to do. I need to take the correct struct by the input type and initialize the struct using 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())
}
Thanks!
You can use interface for the same
AorB := map[string]interface{}{
"a": StructA{},
"b": StructB{},
}
When you retrieve value back you can assert into A for type A and B for type B
Define a interface
type Bin interface {
name() string
set([]byte) // maybe returning error
}
You'll be handling Bin
s only.
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
So your StructA/B are Bins now.
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 you have more than two types: Use a switch instead if an if
or make a tiny type registry (reflect).
First you define an interface
for the commonly used func
name
:
type Namer interface {
name()
}
Then you can create a map to that interface and insert structs:
AorB := map[string] Namer {
"a": StructA{
A: 42,
B: 28,
},
"b": StructB{
C: 12,
},
}
Now you can access all entries:
for _, n := range AorB {
n.name()
}