Map of types in Golang?

huangapple go评论74阅读模式
英文:

Map of types in Golang?

问题

我正在为已知由几种特定类型的帧组成的音频/视频流编写解析器。每种帧类型都有自己的子标题格式,因此我为每种类型定义了一个结构类型,以便将其用作作为第三个参数传递给binary.Read的变量:

type TypeVideoIHeader struct {
    MType       byte // 媒体类型,例如 H.264
    FPS         byte
    Width       byte
    Height      byte
    DateTime    int32
    Length      int32
}

type TypeVideoPHeader struct {
    Length      int32
}

type TypeAudioHeader struct {
    MType       byte
    SampleRate  byte
    Length      int16
}

帧的类型由其头部中的某个字节定义,因此我将它们放入常量中:

type FrameType byte

const (
    VideoI  FrameType = 0xFC
    VideoP  FrameType = 0xFD
    Audio   FrameType = 0xFA
)

现在,在我调用binary.Read之前,我必须创建一个正确类型的变量(上述3个结构之一),函数将使用流中的值填充该变量。

如何仅通过FrameType变量初始化正确类型的变量?是否有一种简洁而优雅的解决方案?

假设这种技巧是可能的:

TMap := map[FrameType]type{
    VideoI: TypeVideoIHeader,
    VideoP: TypeVideoPHeader,
    Audio: TypeAudioHeader,
}

var videoISubHeader TMap[VideoI]
  • 这就是我想要的东西。

英文:

I am writing a parser for audio/video stream which is known to be comprised of frames of several certain types. Each frame type has its own subheader format, so I define a struct type for each to use them for variables passed as the 3rd argument to binary.Read:

type TypeVideoIHeader struct {
    MType       byte // type of media e.g. H.264
    FPS         byte
    Width       byte
    Height      byte
    DateTime    int32
    Length      int32
}

type TypeVideoPHeader struct {
    Length      int32
}

type TypeAudioHeader struct {
    MType       byte
    SampleRate  byte
    Length      int16
}

Which type a frame is is defined by a certain byte in its header, so I put those into constants:

type FrameType byte

const (
    VideoI  FrameType = 0xFC
    VideoP  FrameType = 0xFD
    Audio   FrameType = 0xFA
)

Now, before I can call binary.Read I have to create a variable of the right type (one of the 3 structs above) which the function will fill with values from the stream.

How do I initialise a variable of the right type just by a FrameType variable? Is there a concise and elegant solution?

Say if this kind of trick was possible:

TMap := map[FrameType]type{
    VideoI: TypeVideoIHeader,
    VideoP: TypeVideoPHeader,
    Audio: TypeAudioHeader,
}

var videoISubHeader TMap[VideoI]

— that would be sort of what I am after.

答案1

得分: 7

TMap := map[FrameType]func() interface{} {
    VideoI: func() interface{} { return &TypeVideoIHeader{} },
    VideoP: func() interface{} { return &TypeVideoPHeader{} },
    Audio:  func() interface{} { return &TypeAudioHeader{} },
}

var videoISubHeader = TMap[VideoI]()

if err := binary.Read(r, order, videoISubHeader); err != nil {
    panic(err)
}

请注意,binary.Read 函数期望第三个参数是一个指针,否则它将无法将二进制数据读入传入的变量中,这就是为什么这些函数使用 & 的原因。

英文:
TMap := map[FrameType]func() interface{} {
    VideoI: func() interface{} { return &TypeVideoIHeader{} },
    VideoP: func() interface{} { return &TypeVideoPHeader{} },
    Audio:  func() interface{} { return &TypeAudioHeader{} },
}

var videoISubHeader = TMap[VideoI]()

if err := binary.Read(r, order, videoISubHeader); err != nil {
    panic(err)
}

Note that binary.Read expects the 3rd argument to be a pointer, else it won't be able to read the binary data into the passed in variable, which is why the functions use &.

huangapple
  • 本文由 发表于 2021年7月22日 17:03:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/68482065.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定