Operating on Type in GoLang

I write in a variety of languages both professionally and for fun. Over the past little bit, Google's new language Go has been and increasing percentage of what I write in. I describe it basically as mixing Python and C/C++. Go is mostly a statically typed language and makes for really fast error discovery because you can't pass an integer into a function with the signature of a string.

What happens if I want to do a dynamically typed operation like decoding JSON recursively?

Well, I have an answer for you! recently I had a use case for this decoding a JSON API that gave me strings in JSON format that some of the sub-keys were also strings containing JSON...

I have no idea either, but the hunt was afoot to build a struct, or at least returning an object like:

map[string]interface{}

I know, not much better, but better than just a string. So here is the final product:

package main

import "encoding/json"

/*
 * Little function to recursively unpack JSON
 */
func makeMyObj(message []byte) map[string]interface{} {
    // generate something to return
    final := make(map[string]interface{})
    if err := json.Unmarshal(message, &final); err != {
        // return an empty map because we found nothing here
        return final
    }
    // loop through our keys
    for key, value := range final {
        /*
         * Now lets figure out what type each key is
         * by operating on the type of the value variable
         * and generate the variable v to represent it
         */
        switch v := value.(type) {
        default:
            continue
        case string:
            // Generate a temporary map to hold the object
            var tmp map[string]interface{}
            // attempt to load the string into the function
            tmp = makeMyObj([]byte(v))
            // if the len (amount of keys) is greater than 0 we got JSON!
            if len(tmp) > 0 {
                // add the object to the key
                final[key] = tmp
            }
            else {
                // it wasn't JSON so lets append this string
                final[key] = v
            }
        }
    }
    // final return statement
    return final, nil
}

So what the heck is happening here? Somehow we declared a variable based on its' type?

It broke my brain for quite awhile. basically we are leveraging the runtime to handle variables that are "dynamic" in type. Our switch block allows us to handle the variable "v" based on its' type. This is really powerful because it solves my immediate need to get that project running, but past this; One could modify this code to be a more advanced decision based on the signature of an argument to a function for example. Additionally though we can perform type-safe operations on "v" like casting it to a byte array since we know at that point it is a string.

I'd love to hear feedback and hope it helps another programmer out there. I am committing this year to one programming focused post every month, so here's January.