Go doesn’t have unions, but there’s a hack to do it.
Assume we want to create a union type of a node that may be a text node or a container node that holds text nodes. The following code (playground) demonstrates this:
package main
type node interface {
node()
}
type textNode struct {
text string
}
func (textNode) node() {}
type containerNode []node
func (containerNode) node() {}
func main() {
nodes := []node{
textNode{"hello"},
textNode{" "},
containerNode{
textNode{"world"},
textNode{"!"},
},
}
printNodes(nodes)
}
func printNodes(nodes []node) {
for _, n := range nodes {
switch n := n.(type) {
case textNode:
fmt.Print(n.text)
case containerNode:
printNodes([]node(n))
}
}
}
This trick does in fact give us some type checking during compile time: the following code
switch node := node.(type) {
case string:
}
will error out when built:
impossible type switch case: n (type node) cannot have dynamic type string (missing node method)