Functions
Function definitions and multiple return values
Introduction
In this lesson, you'll learn about functions in Go. Coming from C, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In C, you're familiar with function definitions and multiple return values.
Go has its own approach to function definitions and multiple return values, which we'll explore step by step.
The Go Way
Let's see how Go handles this concept. Here's a typical example:
package main
import "fmt"
func add(a, b int) int {
return a + b
}
// Multiple return values — native
func divmod(a, b int) (int, int) {
return a / b, a % b
}
// Named return values
func divide(a, b float64) (result float64, err error) {
if b == 0 {
err = fmt.Errorf("division by zero")
return
}
result = a / b
return
}
// First-class function
func apply(op func(int, int) int, a, b int) int {
return op(a, b)
}
func main() {
q, r := divmod(17, 5)
fmt.Printf("17/5 = %d rem %d\n", q, r)
fmt.Println(apply(add, 3, 4))
}Comparing to C
Here's how you might have written similar code in C:
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
/* Multiple return: use output params */
void divmod(int a, int b, int *quotient, int *remainder) {
*quotient = a / b;
*remainder = a % b;
}
/* Function pointer */
typedef int (*BinaryOp)(int, int);
int apply(BinaryOp op, int a, int b) {
return op(a, b);
}
int main() {
int q, r;
divmod(17, 5, &q, &r);
printf("17/5 = %d rem %d\n", q, r);
printf("%d\n", apply(add, 3, 4));
}You may be used to different syntax or behavior.
Go natively supports multiple return values; C uses output pointer params
You may be used to different syntax or behavior.
Go function types are inline: func(int, int) int; C uses typedef for function pointers
You may be used to different syntax or behavior.
Go named return values allow bare return statements
You may be used to different syntax or behavior.
Go always requires explicit error returns; C uses errno or out-params
Step-by-Step Breakdown
1. Multiple Returns
Go's killer feature over C: functions can return multiple values directly, eliminating the need for output pointer parameters.
void divmod(int a, int b, int *q, int *r) { *q = a/b; *r = a%b; }func divmod(a, b int) (int, int) { return a / b, a % b }2. Function Types
In Go, function types are written inline — no need for typedef. func(int, int) int is a complete type.
typedef int (*BinaryOp)(int, int);type BinaryOp func(int, int) int
// or inline: func apply(op func(int,int) int, a, b int) int3. Error Handling
Go replaces C's errno and output parameters for errors with a proper error return value — always the last return value by convention.
func readFile(path string) ([]byte, error) {
data, err := os.ReadFile(path)
if err != nil { return nil, err }
return data, nil
}Common Mistakes
When coming from C, developers often make these mistakes:
- Go natively supports multiple return values; C uses output pointer params
- Go function types are inline: func(int, int) int; C uses typedef for function pointers
- Go named return values allow bare return statements
Key Takeaways
- Go multiple returns replace C output pointer params
- Go function types are inline; C uses typedef
- Go error values replace C's errno
- Named returns allow bare return statements