Avoiding Type Assertions in Go

Prefer Polymorphism to Conditionals

Photo by JOSHUA COLEMAN on Unsplash

Since coming to Go from Ruby, I’ve been a lot happier and less stressed out. I used to spend a lot of time admonishing developers to prefer composition to inheritance and avoid optional arguments. Go avoids these arguments by simply (and deliberately) lacking both inheritance and optional args. In general, the recommended best practices contain sage wisdom that can avoid a lot of the mistakes especially common among junior developers.

But one area where I feel the language authors go astray is in their use of type assertions, which tie conditional behavior to types. See this example from the standard library.

// CopyToken returns a copy of a Token.
func CopyToken(t Token) Token {
switch v := t.(type) {
case CharData:
return v.Copy()
case Comment:
return v.Copy()
case Directive:
return v.Copy()
case ProcInst:
return v.Copy()
case StartElement:
return v.Copy()
}
return t
}

What’s so bad about conditionals like these? In short, they scatter behavior about a group of related types across the file system, making change more costly. This leads to a code smell called Shotgun Surgery. Every time a new relevant type is added (or removed), changes will have to be made to statements like this one, across the system. This problem has been eloquently discussed ad nauseam by the inimitable Sandi Metz, who you can see working her magic in this talk.

Sandi Metz teaching us about the benefits of polymorphic design.

Unsurprisingly, the Very Senior Developers on the Go team stumbled right into this mess in the standard library, scattering statements like the one above across multiple files.

The Solution

The easy alternative here is to simply move the method to the respective concrete types which implement the interface (e.g. ). Then the conditional, e.g. the statement, is only needed once, to return the correct type to implement methods like . This notion of using various types to satisfy an expected interface is known as duck typing, and Go thankfully makes it a first class citizen via the keyword. If you find yourself typing , there’s probably a better way.

Advocate of Score Voting and Approval Voting. Software engineer. Father. Husband. American.