Go Doesn't Have Generics
Go doesn’t have generics. This isn’t news, but it’s more foundational than many might realize.
It is widely known that Go does not have generics. I’ve known this since I started with Go, but I recently found that the types, even when using type assertions, are a little stricter than I expected. Let me explain.
🔗 interface{}
Go has interfaces, which are sort of like Java interfaces, except that your code
automatically matches them, as opposed to opting into them. There’s a thing
where you define an empty interface (interface{}
) which means every type
satisfies the interface and thus can be used in place of those types. Here is
an example:
var foo interface{}
foo = "frew"
fmt.Printf("%#v\n", foo);
foo = 1
fmt.Printf("%#v\n", foo);
foo = true
fmt.Printf("%#v\n", foo);
foo = []int{1, 2, 3}
fmt.Printf("%#v\n", foo);
Ok great. So the next interesting thing is that you can use type-assertions to get the underlying, typed value out. Here’s what I mean:
var foo interface{}
foo = 3
var bar int = foo.(int)
fmt.Println(bar)
Without the .(int)
on the third line the above would fail to compile. This
gets interesting with complex types (slices, maps, etc.)
While you can put an int
in an interface{}
, you cannot put a
map[string]int
in a map[string]interface{}
. The following fails to compile:
var foo map[string]interface{}
foo = map[string]int{}
Fundamentally, in Go the type system only ever goes two layers deep, the type of
the variable, and the type of the underlying value. So in the above the
variable is a map[string]interface{}
, which is a distinct type from
map[string]int
. The fact than you can have an interface{}
variable holding
an int
value does not mean that you can have a type containing an
interface{}
match a distinct type containing something else.
Anyway, all of this is just to say that you need to be especially careful with
interface{}
in complex types.
As a side note I am not looking forward to Go getting generics. Much of what keeps the language simple today is the fact that people just cannot build super-abstract code without generics. I suspect that once we get real generics Go code on the internet will stop being the simplicity focused code it is today and instead become abstraction behemoths. I hope I’m wrong.
(The following includes affiliate links.)
If you don’t already know Go, you should definitely check out The Go Programming Language. It’s not just a great Go book but a great programming book in general with a generous dollop of concurrency.
Another book to consider learning Go with is Go Programming Blueprints. It has a nearly interactive style where you write code, see it get syntax errors (or whatever,) fix it, and iterate. A useful book that shows that you don’t have to get all of your programs perfectly working on the first compile.
Posted Mon, Nov 12, 2018If you're interested in being notified when new posts are published, you can subscribe here; you'll get an email once a week at the most.