Last Updated: May 22, 2026
An anonymous function is a function with no name. You write the function literal right where you need it, either to call it on the spot, save it in a variable, or hand it to another function. Go uses anonymous functions for short, one-off pieces of logic that don't deserve a top-level name, for things like inline filters, quick initialization, and goroutines.
A function literal looks exactly like a regular function declaration with the name removed.
The literal func(price float64) float64 { return price * 0.9 } declares a function that takes a float64 and returns a float64. Adding (49.99) right after the closing brace calls it immediately with 49.99 as the argument. The whole thing is an expression, and its value is whatever the function returns.
You can write a function literal anywhere an expression is allowed. That includes the right-hand side of a :=, an argument to another function, or a value inside a slice or map. The key rule is that the literal must have a complete signature: parameter list with types and a return type if it returns anything. Go doesn't infer parameter types for function literals the way some other languages do.
Anonymous functions are first-class values, so you can store one in a variable and call it later, as many times as you want. This is useful when the function isn't worth a top-level declaration but you need to call it more than once inside the surrounding code.
formatPrice is a variable whose type is func(float64) string. You call it with the usual formatPrice(p) syntax. The fact that the original function had no name doesn't matter once it's bound to the variable; the variable name is what you use to call it.
This pattern is common when a helper is only useful inside one function. Declaring a top-level formatPrice would put it in the package namespace forever and expose it to other files in the package, even though only main uses it. Keeping it local to main as an anonymous function says "this is only relevant here" and keeps the package surface clean.
If you write a function literal and call it on the same line, you've written an Immediately Invoked Function Expression, or IIFE. The syntax is func(...) { ... }(), where the trailing () is the call.
The IIFE here builds a configuration map, applies a conditional override, and returns the finished value, all in one expression bound to config. Without the IIFE, you'd either declare a helper function used in exactly one place or scatter the setup logic across several statements before the variable you actually wanted.
The trick is that everything inside the IIFE is scoped to the IIFE. The intermediate name base doesn't leak out into the surrounding function. Only the returned value does. This is the main reason to use an IIFE: you want a private scratch space to compute a value.
Cost: An IIFE costs you one extra function call, which is negligible for setup code. Avoid running an IIFE inside a tight inner loop just for scoping; pull the work outside the loop instead.
The other place anonymous functions shine is as arguments to functions that take other functions. Anonymous functions are how you do that without declaring a named helper for every small task.
The second argument to filter is a function literal that returns true for prices under 10.0. Writing it inline keeps the predicate next to the call that uses it, so a reader sees the filter criteria without jumping to a helper definition elsewhere. If filter needs to be called with different criteria in different places, each call site can pass its own anonymous function and the criteria stays right next to the call.
The signature of the literal has to match what the higher-order function expects. filter expects func(float64) bool, so the literal you pass needs the same parameter and return types. The compiler checks this and reports a clear error if the signatures don't line up.
The most common place you'll see anonymous functions in production Go code is the go func() { ... }() pattern for launching a goroutine.
The go keyword runs whatever follows in a new goroutine. Pairing it with an inline anonymous function lets you launch a small unit of work without writing a separate named function for it. The trailing (p) passes the loop variable into the goroutine as an argument, which is the safe way to hand it data.
We're showing the pattern, not teaching goroutines. For now, just know that go func() { ... }() is the shape you'll see whenever a Go program kicks off background work.
The two styles are interchangeable in raw capability, but they signal different things to a reader. Pick based on what the code is doing.
| Use Anonymous When | Use Named When |
|---|---|
| The logic runs in exactly one place | The same logic is called from multiple places |
| The body is short (a few lines) | The body is long enough to deserve a name |
| You're passing it as an argument inline | The function has independent meaning |
| You need a one-shot scope for setup | It belongs in unit tests on its own |
Anonymous functions are best for one-off use, scoping a small block of work, and inline predicates passed to higher-order calls. If you find yourself copying the same function literal into three different call sites, that's a signal to promote it to a named function. The reverse is also true: a one-line func sumPrices(...) float64 { ... } that's only used once is probably better inlined.