1. 1

    As a recent convert to Go, here are my thoughts…

    The type system is just different. It does feel unlike other languages I’ve used, and it can feel a bit unintuitive at times. For instance, parsing a lot of arbitrary JSON feels like falling into a quagmire of type assertions. My code quickly turns into a wall of text like this:

    data["foo"].(map[string]interface{})["bar"].(map[string]interface{})["baz"].(string)
    

    I know parsing JSON in any typed language can be a pain. I’m still not sure if there’s a better way to do that?

    The other bits that feel confusing is when you can use type conversions vs type assertions. Also, at first glance anonymous fields create types that walk & talk like a Foo, but can’t be converted to a Foo. It took me longer than it should have to realize that the anonymous fields can still be referenced directly. In general, the type system works for me in all the code I write for myself; the only times I’ve had real trouble wrestling with types is when I’m trying to integrate with a library that wasn’t designed to be used the way I was trying to us it. More often than not I feel like I’m trying to fit a square peg into a round hole – as I’m starting to write more library code myself I’m trying to get a better handle on best practices for good go library design.

    As far as Exported Identifiers, the only issues I’ve had were writing a large amount of code with a non-exported field name and then realizing later that I wanted it exported (or vice-versa). The change turns into an O(n) update for every usage of the field as opposed to an O(1) update at the declaration of the field. It just catches you at build time when you miss a reference somewhere, it’s not a big deal as long as you don’t have a long build time. Once again it kinda goes into building a good library from the start – the cost of making a poor API decision early on can translate to a lot of work later trying to fix it.

    1. 8

      You shouldn’t be using JSON like that. You should be defining structures in your program that mirror the data you expect to receive, json.Unmarshaling into them, and accessing the struct fields directly.

      1. 3

        As peterbourgon mentions below, you shouldn’t be unmarshalling everything into a map[string]interface{}, as you lose compile-time type safety.

        If you’re unsure of the JSON that you’ll be receiving, at least use something like mapstructure which will return sensible errors when decoding fails.