Good places to use anonymous functions that aren't just for concurrency

It just occurred to me that I pretty much exclusively use anonymous functions as an easy way to write concurrent and parallel code, with the very, very occasional use of returning a function from another function. Where else is it appropriate to use an anonymous function in go?

Hi @ashinnv,

An anonymous function lives in the context of the function that it is defined in. (This is why anonymous functions are also called “closure”.)

A closure is bound to its outer scope. That is, a closure can access variables defined in the function that the closure is defined in. This way, you can create functions that carry some sort of state with them, for example, a counter, as shown in Go by Example: Closures.

And Jon Calhoun describes 5 Useful Ways to Use Closures in Go.

2 Likes

I most frequently use anonymous functions for less in sort.Slice. sort package - sort - Go Packages

1 Like

Thanks!

1 Like

I also use them as equivalents to C#'s Local Functions. One example I can think of is if I need to build up some metadata for types, such as:

type typeData struct {
    // some data that I want for each type, maybe a mapping of
    // the type's fields to functions that get or set the values, etc.
}

var typeDataByReflectType = sync.Map{}

func getTypeData(rt reflect.Type) *typeData {
    // newTypeData is "local" to getTypeData because you shouldn't be able
    // to call it outside of getTypeData, even from other functions in
    // the same package.
    newTypeData := func(rt reflect.Type) (td *typeData) {
        // do whatever is needed to create one of these *typeData structs
        return
    }
    v, loaded := typeDataByReflectType.Load(rt)
    if loaded {
        return v.(*typeData)
    }
    td := newTypeData(rt)
    if v, loaded = typeDataByReflectType.LoadOrStore(rt, td); loaded {
        return v.(*typeData)
    }
    return td
}
1 Like

Maybe as a callback:

package main

import (
	"fmt"
	"time"
)

type callback func()

func main() {
	doSth(func() {
		fmt.Print("Jobs done")
	})
}

func doSth(c callback) {
	time.Sleep(time.Second * 2) // to simulate some tasks
	c()
}
3 Likes