Maybe I'm not fully versed on the power of generics, but how is the empty interface, interface{}
, different than a generic, especially if we have the ability to use reflection or type switches? People always mention that Go doesn't have generics, but interface{}
seems like it does the job pretty comparable to something like <T>
in Java.
-
This question is about a theoretical difference between Go's `interface{}` and generics in other languages. Starting with Go 1.18, Go has its own implementation of parametric polymorphism. If you are interested in that, see: [Difference between any/interface{} as constraint vs. type of argument?](https://stackoverflow.com/questions/71628061/difference-between-any-interface-as-constraint-vs-type-of-argument) – blackgreen May 07 '23 at 06:04
2 Answers
If you come from Java, the empty interface (interface{}
) is actually closer to working with Object
variables in Java than with generics.
You can assign anything to an interface{}
(like you can do with an Object
variable in Java).
But you should then "cast" or "type assert" back if you want to use the actual type you stored there (same that you need to do with Object
variables in Java).
Generics in Java are quite different, since they allow you to keep type checking at compile time. The difference is precisely that you don't need to resort to reflection or type switches if you work with Generics.
You can read more about Java generics here:
https://docs.oracle.com/javase/tutorial/java/generics/
And then follow this and the next 2 or 3 steps of the Go tour here for more on how the empty interface works:

- 34,399
- 18
- 41
- 57

- 11,825
- 28
- 35
-
2So is the main difference that in Go that it's checked at runtime, rather than compile time? – ollien Jul 18 '17 at 16:20
-
Well, one can also check if the interface is implemented at compile time by simply calling the function - see https://stackoverflow.com/a/44692363/2969090 – Ravi R Jul 18 '17 at 16:36
-
2That example is not working with interface{} variables but rather with typed variables. You can check at compile time if a type implements an interface, you cannot check if an interface{} is of a given type at compile time. – eugenioy Jul 18 '17 at 16:43
-
Not to mention with Go, type assertion allows you to see and use the underlying type. With generics, you are essentially giving up knowing your type. – Gavin Jul 18 '17 at 16:43
Considering the main point of generics is to maintain the compile-time type safety check for statically typed languages when providing facilities to write type agnostic functions/methods, the empty interface with runtime type assertions/switches is completely different from generics and I'd say it's almost the complete opposite to generics in terms of programming paradigms.
I'd say more than half of the programming language improvements over the last decade are about avoiding runtime errors, and I guess that's why Go has some "built-in generics" like slice and map instead of something like the old JavaScript's Array stuff which only has type checks on its elements during run-time. So the empty interface with type assertion/switch in Go is definitely no replacement for generics and personally, I'd try to avoid using the empty interface as much as possible.

- 924
- 8
- 15