与不同大小的字段互换结构

问题描述 投票:0回答:1

我有两个结构,用于解析输入二进制文件中的数据。

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 个字节。名称和顺序相同。

有没有办法让函数可以互换使用这些函数?除了使用带有大量吸气剂的接口之外,我找不到任何明显的东西。

go struct
1个回答
0
投票

在 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)
}

另请参阅此类似问题

© www.soinside.com 2019 - 2024. All rights reserved.