Lab 02: Functions, Closures & Defer
Objective
Time
Prerequisites
Tools
Lab Instructions
Step 1: Multiple Return Values
docker run --rm zchencow/innozverse-go:latest go run - << 'EOF'
package main
import (
"errors"
"fmt"
"strconv"
)
// Multiple returns — the Go way to handle errors
func safeDivide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
// Named return values — self-documenting
func stats(nums []float64) (mean, stddev float64, err error) {
if len(nums) == 0 {
err = errors.New("empty slice")
return
}
for _, n := range nums {
mean += n
}
mean /= float64(len(nums))
for _, n := range nums {
diff := n - mean
stddev += diff * diff
}
stddev = stddev / float64(len(nums))
return // naked return — returns named values
}
func parseInts(strs []string) ([]int, []error) {
results := make([]int, 0, len(strs))
errs := make([]error, 0)
for _, s := range strs {
n, err := strconv.Atoi(s)
if err != nil {
errs = append(errs, fmt.Errorf("cannot parse %q: %w", s, err))
} else {
results = append(results, n)
}
}
return results, errs
}
func main() {
if result, err := safeDivide(10, 3); err != nil {
fmt.Println("Error:", err)
} else {
fmt.Printf("10/3 = %.4f\n", result)
}
_, err := safeDivide(1, 0)
fmt.Println("Error:", err)
data := []float64{2, 4, 4, 4, 5, 5, 7, 9}
mean, variance, err := stats(data)
fmt.Printf("mean=%.2f variance=%.2f err=%v\n", mean, variance, err)
nums, errs := parseInts([]string{"1", "2", "abc", "4", "xyz"})
fmt.Println("Parsed:", nums)
fmt.Println("Errors:", len(errs))
}
EOFStep 2: Variadic & Functional Arguments
Step 3: First-Class Functions & Higher-Order Functions
Step 4: Closures
Step 5: Defer
Step 6: Recursion & Tail Calls
Step 7: init() & Package-Level Functions
Step 8: Capstone — Pipeline of Functions
Summary
Concept
Key points
Further Reading
Last updated
