Type Assertions In Go Are Weird

I’ve been using Go a bit more lately for a side project I’m working on and I ran into a few instances where I needed to do use type assertions for some fairly flexible interfaces. While I could easily do what I needed to, it still feels weird.

Here’s the first example of a type assertion where we test the config variable to see if it is of type arg_parser.BulkConfig and if so, we check ok which we get as part of the tuple result to then use in our conditional logic. It works, but just feels pretty strange. Really makes me miss Rust’s pattern matching.

if bulk, ok := config.(arg_parser.BulkConfig); ok {
    size = bulk.Size
}

And here is a more complex example which really felt weird. Instead of a concrete type in the type assertion, we can use type and then use a switch statement to match the underlying concrete type. Again, this totally works, but it just feels so strange!

switch a := arg.(type) {
case arg_parser.TextArg:
    task.Title = a.Text
case arg_parser.TagArg:
    task.Tags = append(task.Tags, a.Tag)
case arg_parser.ScopedArg:
    if a.Scope == arg_parser.ScopePriority {
        task.Priority = a.Value
    } else {
        printer.Error(fmt.Errorf("Missing value for \"%s:\"", a.Scope))
    }
}

This is one of those things in Go that just takes getting used to. So many parts of Go feel so wrong at first, but then after using it for a while, you end up realizing that the simplicity of Go is so worth the fact that a few things feel a little weird at first.