Duck Typing (horror) in Go
by C. Campo - 4 min read
If you say Go supports “duck typing” online, you’ll probably get some pushback. The Go community often points out that Go doesn’t support duck typing because it’s statically typed, and duck typing is a feature of dynamically typed languages. Rather, Go has “structural typing” where interfaces are still implicitly implemented, but still checked at compile time.
Here’s an example of structural typing in Go:
Give a try.
Both Mallard
and Goose
implicitly implement the Duck
interface, so they
can be assumed to be a Duck
at compile time, and in this example, in the
quack
function. A Goose
swims like a Duck
and quacks like a Duck
, so it
must be a Duck
!
So how isn’t this duck typing? Well, it’s a bit of a pedantic argument, but duck typing is typically associated with dynamically typed languages, where the types are determined at runtime rather than compile time like here.
From Wikipedia:
Duck typing is similar to, but distinct from, structural typing. Structural typing is a static typing system that determines type compatibility and equivalence by a type’s structure, whereas duck typing is dynamic and determines type compatibility by only that part of a type’s structure that is accessed during runtime.
With that definition in hand, can we do duck typing in Go? Well, when using the language as intended, no. But if you’re willing to hack around the type system a bit, you can still write this horror show:
Go ahead… run it!
I would say that Go can duck type with the best of em!
PS: please don’t write real code like this! I’m just having some in this post! It’s really a bad idea. Don’t do it. This example is intended to panic!
My point is just to show that while it is often said that Go doesn’t support
duck typing, you can write something that looks awfully a lot like duck typing
if you (mis)use some of the more “dynamic” features of the language like any
and type assertions and hack around the type system. It doesn’t even require
reflection, as one might expect, such as in Java1,
2. It is essentially the Go analogue of the
Wikipedia duck typing example in Python.
And if the code looks and behaves like duck typing, then it must duck typing ;).
Please note that there are very valid use cases for any
and type assertions,
but duck typing is not one of them!
Of course, the “correct” implementation of the quack
function would be to
accept Duck
instead of any
and ditch the type assertions, which will result
a compile time error. This is the first example in this post.
Even if for whatever reason you were stuck with using any
, you could still use
the two-valued type assertion (or a type switch) to check if the
type implements Duck
, which of course is still a runtime check, but at least
it avoids the panic:
See here for the output.
Still, always prefer using the type system and the compiler to your advantage whenever possible!
Thanks for reading!
Subscribe via RSS