Go · Anonymous functions

Anonymous functions

Go has anonymous functions, hardly “News at 11” but developers should know how these functions are defined and used.

Anonymous functions are functions that are defined with no name, and that is almost all that separates them from other functions.

func (){
    fmt.Println("Anonymous")
}

Anonymous functions are either called where they are defined with the brackets at the end of the definition or the variable they are assigned to has brackets appended when the call is made.

If an anonymous function is defined outside of another function, then it has package scope. But that anonymous function must be assigned to a variable so that it can be referred to, and called.

// Definition
var f func() = func() {fmt.Println("Package scoped anonymous function")}

func main() {
    // Call
    f()
}

Or they can be nested inside other functions.

func main() {
    // Definition and call
    func() {fmt.Println("Function scoped anonymous function")}()
}

Nested anonymous functions can also be assigned to variables

func main() {
    // Definition
    f := func() {fmt.Println("Function scoped anonymous function")}

    // Call
    f()
}

Anonymous functions can be passed values either explicitly

func main() {
    name := "Funky"
    func(s string) {fmt.Printf("Function scoped anonymous function with name %s\n", s)}(name)
}

Or via closures

func main() {
    name := "Funky"
    func() {fmt.Printf("Function scoped anonymous function with name %s\n", name)}()
}

Anonymous functions can also be launched by goroutines

func main() {
    var wg sync.Waitgroup
    name := "Funky"

    wg.Add()
    go func(s string, wg *sync.Waitgroup) {
        defer wg.Done()
        fmt.Printf("Function scoped anonymous function with name %s\n", s)}(name, &wg)
}
    wg.Wait()

Because functions are types, they can be passed to other functions or methods, and returned

func main() {
    // Call TakesFunc with an anonymous function
    s := TakesFunc(func() string {
        return "first"
    })
    // Call the function that TakesFunc returned
    fmt.Printf("I got %s\n", s())
 
    // Note that variable s was created and used to make the example clearer, this will work as well
    fmt.Println("Indecipherable", TakesFunc(func() string {
        return "first"
    })())
}

func TakesFunc(f func() string) func() (string) {
    // Call the anonymous function passed to TakesFunc
    fmt.Println("Calling f():", f())
    
    // return an anonymous function
    return func() (string) {
        return "Inside"
    }
}

And even given methods of their own

// Define type
type T func()

// Create a method on the type
func (t *T) tF() {
	fmt.Println("Type method")
}

func main() {
    // Create an instance of type T with an anonymous function
    f := T(func() { fmt.Println("Creation") })
    // Call the anonymous function
    f()
    // Call the method on the anonymous function
    f.tF()
}

That’s everything to demonstrate for anonymous functions, if you find different uses let me know!

Published:
comments powered by Disqus