我有两个结构,用于解析输入二进制文件中的数据。
type MyStruct32 struct {
field1 uint32
field2 uint32
field3 uint32
...
}
type MyStruct64 struct {
field1 uint64
field2 uint64
field3 uint64
...
}
我这样解析数据:
var o MyStruct32
err := binary.Read(bytes.NewBuffer(data[offset:]), binary.LittleEndian, &o)
唯一的区别是 32 位版本每个字段使用 4 个字节,64 位版本每个字段使用 8 个字节。名称和顺序相同。
有没有办法让函数可以互换使用这些函数?除了使用带有大量吸气剂的接口之外,我找不到任何明显的东西。
在 Discord 上的一些帮助下,我发现了如何使用 generics 来实现我在现代版本的 Go 中所做的事情。
下面的示例程序将:
MyData
,可以具有 struct
或 uint32
字段的 uint64
。printGenericStruct(..)
。[]byte
数组中解析两个结构,以表明泛型可以与 binary.Read(..)
一起使用。package main
import (
"bytes"
"encoding/binary"
"log/slog"
)
type MyData[WordSize uint32 | uint64] struct {
Field1 WordSize
Length uint32
Field2 WordSize
}
func printGenericStruct[WordSize uint32 | uint64](s MyData[WordSize]) {
slog.Info("Field 1", "field1", s.Field1, "field2", s.Field2, "length", s.Length)
}
func main() {
a := MyData[uint32]{0, 0, 1}
b := MyData[uint64]{100, 1, 101}
printGenericStruct(a)
printGenericStruct(b)
data := []byte{1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
offset := 0
var c MyData[uint32]
err := binary.Read(bytes.NewBuffer(data[offset:]), binary.LittleEndian, &c)
if err != nil {
panic(err)
}
printGenericStruct(c)
var d MyData[uint64]
err = binary.Read(bytes.NewBuffer(data[offset:]), binary.LittleEndian, &d)
if err != nil {
panic(err)
}
printGenericStruct(d)
}
另请参阅此类似问题。