Named Return Values
func name(param type) (result type, err error) {
// body
return
}
Declaring Named Returns
Instead of only listing return types, a function can give each return value a name in the signature, which both documents its purpose and pre-declares it as a usable local variable initialized to its zero value.
Example: Declaring Named Returns
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define the function rectangleStats
func rectangleStats(w, h float64) (area, perimeter float64) {
area = w * h
perimeter = 2 * (w + h)
return
}
// main is where the program starts running
func main() {
// Short declaration: create a, p and infer the type
a, p := rectangleStats(4, 3)
// Print the values followed by a newline
fmt.Println("area:", a, "perimeter:", p)
}
Login to try C/C++/Java/PHP code in the editor
Bare return Statements
When return values are named, a plain return with no arguments automatically returns whatever those named variables currently hold, saving you from repeating the variable names.
Example: Bare return Statements
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define the function splitName
func splitName(full string) (first, last string) {
first = "Go"
last = "Pher"
return
}
// main is where the program starts running
func main() {
// Short declaration: create f, l and infer the type
f, l := splitName("gopher")
// Print the values followed by a newline
fmt.Println(f, l)
}
Login to try C/C++/Java/PHP code in the editor
Named Returns with error
Named returns are especially common for the value/error pattern, where naming the error variable err makes the function body read naturally as you set it inside conditionals before returning.
Example: Named Returns with error
// Every Go file belongs to a package; main builds an executable
package main
// Import the packages this program uses
import (
"errors"
"fmt"
)
// Define the function validateAge
func validateAge(age int) (valid bool, err error) {
// Check whether age < 0
if age < 0 {
err = errors.New("age cannot be negative")
return
}
valid = true
return
}
// main is where the program starts running
func main() {
// Short declaration: create ok, err and infer the type
ok, err := validateAge(-3)
// Print the values followed by a newline
fmt.Println(ok, err)
}
Login to try C/C++/Java/PHP code in the editor
- Overusing named returns in long functions, which makes it hard to track where each named value actually gets set.
- Shadowing a named return variable with := inside the function body, creating a separate local variable that a bare return won't pick up.
- Assuming named returns are required for multiple return values -- they're just an optional documentation/convenience feature.
- Named return values give return parameters names right in the function signature.
- A bare return with no arguments sends back the current values of the named returns.
- Named returns act as pre-declared, zero-valued local variables inside the function.
- They're most useful for short functions and for documenting what each return value means.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: