GO

Go Fundamentals

18 lessons

Progress0%
1. Introduction to Go
1What is Go?
2. Variables and Data Types
1Data Types in Go
3. Control Flow
If, For, and SwitchDefer, Panic, Recover
4. Functions
Function BasicsError Handling
5. Structs and Methods
StructsMethods and Interfaces
6. Concurrency
Goroutines and ChannelsSelect and Sync
7. Maps & Slices Advanced
Slices Deep DiveMaps Operations & Patterns
8. Interfaces Deep Dive
Interface Composition & anyCommon Interfaces & Patterns
9. Packages & Modules
Package SystemGo Modules & Workspace
10. Testing & Standard Library
Testing in GoStandard Library Essentials
All Tutorials
GoFunctions
Lesson 5 of 18 min
Chapter 4 · Lesson 1

Function Basics

Functions in Go

Go functions are first-class values. They can be assigned to variables, passed as arguments, and returned from other functions.

Named return values Name the return variables in the signature for documentation and bare returns:

go
func minMax(arr []int) (min, max int) { … return }

Variadic functions A variadic parameter accepts zero or more values of a type (must be last):

go
func sum(nums ...int) int { … }
sum(1, 2, 3)
sum(slice...)  // spread a slice

Closures A closure captures variables from its surrounding scope:

go
func counter() func() int {
    n := 0
    return func() int { n++; return n }
}

First-class functions Functions can be stored in variables, passed as arguments, and returned:

go
apply := func(f func(int) int, x int) int { return f(x) }

Key points:

  • Multiple return values are idiomatic in Go (used extensively for error handling).
  • Closures share the captured variable, not a copy.
  • Anonymous functions can be called immediately: func() { … }().

Code Examples

Named returns and variadic functionsgo
package main

import "fmt"

func stats(nums ...int) (min, max, sum int) {
	if len(nums) == 0 {
		return
	}
	min, max = nums[0], nums[0]
	for _, n := range nums {
		sum += n
		if n < min { min = n }
		if n > max { max = n }
	}
	return
}

func main() {
	min, max, sum := stats(3, 1, 4, 1, 5, 9, 2, 6)
	fmt.Printf("min=%d max=%d sum=%d\n", min, max, sum)

	values := []int{10, 20, 30}
	_, _, total := stats(values...)
	fmt.Println("total:", total)
}

Named return values are initialized to zero values. A bare return returns the current named values. The ... spreads a slice into variadic args.

Closures and first-class functionsgo
package main

import "fmt"

func makeMultiplier(factor int) func(int) int {
	return func(x int) int {
		return x * factor
	}
}

func apply(nums []int, fn func(int) int) []int {
	result := make([]int, len(nums))
	for i, n := range nums {
		result[i] = fn(n)
	}
	return result
}

func main() {
	double := makeMultiplier(2)
	triple := makeMultiplier(3)

	fmt.Println(double(5))
	fmt.Println(triple(5))

	nums := []int{1, 2, 3, 4, 5}
	fmt.Println(apply(nums, double))
}

makeMultiplier returns a closure that captures factor. apply demonstrates passing functions as arguments (higher-order functions).

Quick Quiz

1. What does `...` after a slice name do when calling a variadic function?

2. What does a closure capture from its enclosing scope?

Was this lesson helpful?

PreviousNext