With foundational background in dynamically typed programming languages, I’m struggling to return to phrases with static typing.
Static typing itself would have been high-quality if it wasn’t inflicting the necessity to both violate the DRY precept, or use performance-costly reflection in sure conditions. Like on this one:
Say we have to write a video stream parser. Video binary knowledge is comprised of frames, every having a kind, a sure header construction and a payload. My CCTV cameras produce streams of 5 body sorts (video key, video non-key, audio, nonetheless image and data), however for simplicity let’s take into account solely 2, simplified sorts. Full instance with some pretend knowledge:
bundle predominant
import (
"fmt"
"encoding/binary"
"bytes"
"io"
)
sort Kind byte
const (
Video Kind = 0xFC
Audio Kind = 0xFA
)
var HMap = map[Type]string {
Video: "Video",
Audio: "Audio",
}
sort CommonHeader struct {
Kind Kind
}
sort Header interface {
GetLength() int
}
sort HeaderVideo struct {
Width uint16
Peak uint16
Size uint32
}
sort HeaderAudio struct {
SampleRate uint16
Size uint16
}
func (h HeaderVideo) GetLength() int {
return int(h.Size)
}
func (h HeaderAudio) GetLength() int {
return int(h.Size)
}
var TMap = map[Type]func() Header {
Video: func() Header { return &HeaderVideo{} },
Audio: func() Header { return &HeaderAudio{} },
}
func predominant() {
knowledge := bytes.NewReader([]byte{0xFC, 0x80, 0x07, 0x38, 0x04, 0x02, 0x00, 0x00, 0x00, 0xFF, 0xAF, 0xFA, 0x10, 0x00, 0x01, 0x00, 0xFF})
var cHeader CommonHeader
for {
err := binary.Learn(knowledge, binary.LittleEndian, &cHeader)
if err != nil {
break
}
fmt.Println(HMap[cHeader.Type])
body := TMap[cHeader.Type]()
binary.Learn(knowledge, binary.LittleEndian, body)
fmt.Println(body)
payload := make([]byte, body.GetLength())
io.ReadFull(knowledge, payload)
fmt.Println(payload)
}
}
See — precisely the identical implementation of the GetLength()
methodology must be repeated for every body sort. Not an enormous deal I hear you say. Certainly, on this case. Even when repeated 5 instances in the actual code (5 body sorts). However the reality stays: the code can’t be DRYed in precept. Until utilizing reflection:
func GetLength(body any) int {
return int(mirror.ValueOf(body).Elem().FieldByName("Size").Uint())
}
var TMap = map[Type]func() any {
Video: func() any { return &HeaderVideo{} },
Audio: func() any { return &HeaderAudio{} },
}
So, I’m simply questioning: how do the present authors of Go see this drawback? Is it recognised? Will it’s tackled in some unspecified time in the future? Or do they not see it an issue in any respect?