Go figure

Learning a new programming language is painful sometimes. I remember when I was learning Python, and I would run into language quirks all the time. It was only after suffering through a few embarrassing pull requests that I finally grokked the dang thing.

The same thing is happening to me in Go. Let’s say you have two structs that have the same field:

type A struct {
    C string
}

type B struct {
    C string
}

and then you have a list of interfaces that include two of these:

interfaces := []interface{}{A{"hello"}, B{"world"}}

In this reduced example, all I wanted to do was access C from both of these. It seemed natural to use a type switch:

for _, value := range interfaces {
    switch c := value.(type) {
    case A, B:
        fmt.Println(c.C)
    }
}

Uh oh. Go complains that c is still an interface, and as a result has no field C. That’s really strange, because this definitely works:

for _, value := range interfaces {
    switch c := value.(type) {
    case A:
        fmt.Println(c.C)
    case B:
        fmt.Println(c.C)
    }
}

So what doesn’t work with a compound case statement works just fine when you break the statement up into multiple cases. This baffled me.

It took some creative Googling to find this gem in the spec:

The TypeSwitchGuard may include a short variable declaration. When that form is used, the variable is declared at the end of the TypeSwitchCase in the implicit block of each clause. In clauses with a case listing exactly one type, the variable has that type; otherwise, the variable has the type of the expression in the TypeSwitchGuard.

In non-Golangese, this just means that a case has a single listing, the variable after switch takes on the type of the case. If the case has more than one listing, it stays its original type, which is interface{}.

I wish this type of thing would be more obvious. I expected the first pattern to be fully acceptable, or error out if compilation finds that one of the types doesn’t have a C field. It’s more expressive and avoids duplication, both strong indicators of a proper language construct. Go figure, I guess.

 
4
Kudos
 
4
Kudos

Now read this

Two weeks

It’s been two weeks since I told my bosses that in two weeks I would be spending my last day at work, which is today. There’s no stranger feeling than watching slowly as my relationships with people I’ve worked with these last three and... Continue →