Using Go Without Generics
source link: https://nigeltao.github.io/blog/2021/using-go-without-generics.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
nigeltao.github.io
Using Go Without Generics
Go 1.17 was recently released, per the
“release twice a year”
schedule. As always, there’s a bunch of commentators noting that it still
doesn’t have generics yet (it’s a work in
progress and there’s a lot of work).
Sometimes this is expressed as if Go code must therefore be littered with
numerous uses of the empty interface{}
type.
Here’s one counter-anecdote, where interface{}
just isn’t that frequent,
whether that’s “interface{}
approximating generics” or otherwise. The Wuffs
codebase is about 60k lines of Go code. Even
after accounting that about 25% of that is a
generated data
table (the Wuffs compiler’s pre-parsed equivalent of
arm_neon.h
),
it’s still not a small or toy set of programs:
$ git show | head -n 1
commit 1d191576683c97e8e3c59258f7dca9a010a10754
$ find . -name *.go | xargs wc -l | tail -n 1
60106 total
$ wc -l lib/armneonintrinsics/data.go
16713 lib/armneonintrinsics/data.go
In that whole corpus, interface{}
is only used three times.
$ rg 'interface\{\}'
script/print-crc32-x86-sse42-magic-numbers.go
69:func debugf(format string, a ...interface{}) {
script/print-file-sizes-json.go
100:type dir map[string]interface{}
internal/cgen/cgen.go
232:func (b *buffer) printf(format string, args ...interface{}) { fmt.Fprintf(b, format, args...) }
Two of those three simply mimic the
fmt.Printf
signature, whose arguments can
indeed have varied types.
The last one, in a 99 line
program,
admittedly does use interface{}
where other languages would use some sort of
type-safe enum or union. But I don’t think generics would change anything here.
In a similar vein, this repository full of Go code also doesn’t use reflection
at all, other than a couple of
reflect.DeepEqual
calls in tests:
$ find . -name *.go | xargs rg -w reflect
./lang/check/check_test.go
21: "reflect"
167: if !reflect.DeepEqual(got, want) {
./lib/compression/compression_test.go
18: "reflect"
35: if !reflect.DeepEqual(got, want) {
In conclusion, yes, generics are useful, and plenty of people want them in Go, for good reason. But you can also still get plenty done in Go without them.
Published: 2021-08-22
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK