Go's return values may be named. If so, they are treated as variables defined at the top of the function.
These names should be used to document the meaning of the return values.
A return statement without arguments returns the named return values. This is known as a "naked" return.
Naked return statements should be used only in short functions. They can harm readability in longer functions.
package main
import "fmt"
func do() (b bool) {
// var b bool << imagine the compiler added this
return
}
func main() {
fmt.Println(do()) // false
}
Here's a real example of using the 'zero' value properties of named returns.
In this example we have a GetString
which will return a default value if a key isn't found. It does this by internally calling GetStringDefault
and passing it the named return variable val
that GetString
has defined.
package main
import (
"fmt"
)
func GetString(key string) (val string) {
// 'named' return value are initialized to their zero value
// meaning we can proxy the zero value through to a nested function
//
return GetStringDefault(key, val)
}
func GetStringDefault(key string, defaultValue string) string {
m := map[string]string{
"foo": "bar",
"abc": "xyz",
}
v, ok := m[key]
if !ok {
return defaultValue
}
return v
}
func main() {
defaultValue := "no key found"
// if you care about getting a default value back
// then use the GetStringDefault function
//
fmt.Println(GetStringDefault("foo", defaultValue)) // bar
fmt.Println(GetStringDefault("abc", defaultValue)) // xyz
fmt.Println(GetStringDefault("xxx", defaultValue)) // no key found
// if you don't care about getting a default value back
// then use the GetString function, and you'll now get back a zero value
//
fmt.Println(GetString("foo")) // "bar"
fmt.Println(GetString("abc")) // "xyz"
fmt.Println(GetString("xxx")) // "" << zero value for type string
}