Golang: weird syntax in environmentasmap.go

Viewed 33

I've stumbled upon this piece of code and two variables & function declarations from it look weird as hell:

getenvironment := func(data []string, getkeyval func(item string) (key, val string)) map[string]string {...}
environment := getenvironment(os.Environ(), func(item string) (key, val string) {

I understand what the code does in general, but these two lines just freak me out. Is it even okay to write like this? How do these unnamed (func(item string)) and empty (getkeyval) functions work?

2 Answers

getenvironment is a function variable that is a function that takes a []string, and another function getkeyval. The getkeyval function is expected to get a string item, and return key,val string values. The getenvironment function returns a map.

The second snippet calls that function, passing an anonymous function for getkeyval.

The first line assigns a function literal to a variable called getenvironment. The first parameter of a call to that function needs to be of type []string. The second parameter needs to be of type func(string) (string, string).

The second line calls the function literal assigned to getenvironment, where the value returned by os.Environ() is of type []string and

func(item string) (key, val string) {
    splits := strings.Split(item, "=")
    key = splits[0]
    val = splits[1]
    return
}

is of type func(string) (string, string).

A thing to not get thrown off by here is the names of the parameters and return values. These don't affect a function's signature, and purely serve the purpose of documentation/code readability.

The whole logic could be collapsed into a single function declaration like so:

func getenvironment(data []string) map[string]string {
    items := make(map[string]string)
    for _, item := range data {
        splits := strings.Split(item, "=")
        key := splits[0]
        val := splits[1]
        items[key] = val
    }
    return items
}
Related