#Go Functions
Functions are the basic unit for organizing and reusing code. Go's function design is concise yet powerful, supporting multiple return values, named return values, variadic parameters, and more. This chapter covers the various ways to use Go functions in detail.
#📋 Function Basics
#Function Declaration and Definition
package main
import "fmt"
// 基本函数语法: func 函数名(参数列表) 返回类型 { 函数体 }
func greet() {
fmt.Println("Hello, World!")
}
// 带参数的函数
func greetPerson(name string) {
fmt.Printf("Hello, %s!\n", name)
}
// 带返回值的函数
func add(a, b int) int {
return a + b
}
// 多个参数,多个返回值
func calculate(a, b int) (int, int, int, int) {
return a + b, a - b, a * b, a / b
}
func main() {
// 调用函数
greet()
greetPerson("Go")
result := add(5, 3)
fmt.Printf("5 + 3 = %d\n", result)
sum, diff, product, quotient := calculate(20, 4)
fmt.Printf("20 和 4 的运算结果: 和=%d, 差=%d, 积=%d, 商=%d\n",
sum, diff, product, quotient)
}#Function Parameters
#Pass by Value
func main() {
// Go 语言是值传递
x := 10
fmt.Printf("调用前 x = %d\n", x)
modifyValue(x)
fmt.Printf("调用后 x = %d\n", x) // x 仍然是 10
// 如果需要修改原值,需要传递指针
fmt.Printf("调用指针函数前 x = %d\n", x)
modifyPointer(&x)
fmt.Printf("调用指针函数后 x = %d\n", x) // x 变成了 20
}
func modifyValue(num int) {
num = 100
fmt.Printf("函数内 num = %d\n", num)
}
func modifyPointer(num *int) {
*num = 20
fmt.Printf("函数内 *num = %d\n", *num)
}#Slice and Map Parameters
func main() {
// 切片是引用类型,修改会影响原切片
numbers := []int{1, 2, 3, 4, 5}
fmt.Printf("修改前: %v\n", numbers)
modifySlice(numbers)
fmt.Printf("修改后: %v\n", numbers)
// 映射也是引用类型
scores := map[string]int{"Alice": 85, "Bob": 92}
fmt.Printf("修改前: %v\n", scores)
modifyMap(scores)
fmt.Printf("修改后: %v\n", scores)
}
func modifySlice(slice []int) {
slice[0] = 100 // 修改第一个元素
slice = append(slice, 6, 7, 8) // 注意:append 可能不会影响原切片
}
func modifyMap(m map[string]int) {
m["Charlie"] = 78 // 添加新元素
m["Alice"] = 95 // 修改现有元素
}#Return Values
#Multiple Return Values
import (
"errors"
"fmt"
"math"
)
func main() {
// 处理多返回值
quotient, remainder, err := divide(10, 3)
if err != nil {
fmt.Printf("错误: %v\n", err)
} else {
fmt.Printf("10 ÷ 3 = %d 余 %d\n", quotient, remainder)
}
// 忽略某些返回值
_, remainder2, _ := divide(17, 5)
fmt.Printf("17 除以 5 的余数: %d\n", remainder2)
// 数学运算函数
result, isValid := sqrt(16)
if isValid {
fmt.Printf("√16 = %.2f\n", result)
}
result2, isValid2 := sqrt(-4)
if !isValid2 {
fmt.Println("负数没有实数平方根")
}
}
func divide(a, b int) (int, int, error) {
if b == 0 {
return 0, 0, errors.New("除数不能为零")
}
return a / b, a % b, nil
}
func sqrt(x float64) (float64, bool) {
if x < 0 {
return 0, false
}
return math.Sqrt(x), true
}#Named Return Values
func main() {
// 使用命名返回值的函数
area, perimeter := rectangleCalculations(5, 3)
fmt.Printf("矩形面积: %.2f, 周长: %.2f\n", area, perimeter)
// 错误处理示例
result, err := parseAndCalculate("10", "5")
if err != nil {
fmt.Printf("错误: %v\n", err)
} else {
fmt.Printf("结果: %d\n", result)
}
}
// 命名返回值
func rectangleCalculations(length, width float64) (area, perimeter float64) {
area = length * width
perimeter = 2 * (length + width)
return // 不需要指定返回值,会自动返回命名的变量
}
// 命名返回值在错误处理中很有用
func parseAndCalculate(aStr, bStr string) (result int, err error) {
var a, b int
// 解析第一个数字
if a, err = parseInt(aStr); err != nil {
return // 相当于 return 0, err
}
// 解析第二个数字
if b, err = parseInt(bStr); err != nil {
return
}
result = a + b
return // 相当于 return result, nil
}
func parseInt(s string) (int, error) {
// 简单的字符串转整数实现
if s == "10" {
return 10, nil
} else if s == "5" {
return 5, nil
}
return 0, errors.New("无法解析字符串")
}#🔄 Variadic Functions
#Basic Variadic Parameters
func main() {
// 可变参数函数调用
fmt.Printf("无参数调用: %d\n", sum())
fmt.Printf("单个参数: %d\n", sum(5))
fmt.Printf("多个参数: %d\n", sum(1, 2, 3, 4, 5))
// 传递切片给可变参数函数
numbers := []int{10, 20, 30, 40}
fmt.Printf("传递切片: %d\n", sum(numbers...)) // 使用 ... 展开切片
// 字符串连接示例
message := concatenate("Hello", " ", "Go", " ", "World", "!")
fmt.Printf("连接结果: %s\n", message)
// 格式化消息
formattedMsg := formatMessage("用户 %s 的分数是 %d", "Alice", 95)
fmt.Println(formattedMsg)
}
// 可变参数函数:计算总和
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
// 字符串可变参数
func concatenate(strings ...string) string {
result := ""
for _, str := range strings {
result += str
}
return result
}
// 混合参数(固定参数 + 可变参数)
func formatMessage(format string, args ...interface{}) string {
// 简单的格式化实现
return fmt.Sprintf(format, args...)
}#Advanced Variadic Usage
import "reflect"
func main() {
// 类型安全的可变参数处理
printInts(1, 2, 3, 4, 5)
printStrings("Hello", "World", "Go")
// 通用打印函数
printValues("混合类型:", 42, "Hello", 3.14, true)
// 统计函数
stats := calculateStats(85, 92, 78, 96, 88, 91)
fmt.Printf("统计结果: %+v\n", stats)
}
func printInts(numbers ...int) {
fmt.Print("整数: ")
for i, num := range numbers {
if i > 0 {
fmt.Print(", ")
}
fmt.Print(num)
}
fmt.Println()
}
func printStrings(strings ...string) {
fmt.Print("字符串: ")
for i, str := range strings {
if i > 0 {
fmt.Print(", ")
}
fmt.Printf("\"%s\"", str)
}
fmt.Println()
}
// 处理任意类型的可变参数
func printValues(prefix string, values ...interface{}) {
fmt.Print(prefix + " ")
for i, value := range values {
if i > 0 {
fmt.Print(", ")
}
fmt.Printf("%v(%T)", value, value)
}
fmt.Println()
}
// 统计数据结构
type Statistics struct {
Count int
Sum float64
Average float64
Min float64
Max float64
}
func calculateStats(values ...float64) Statistics {
if len(values) == 0 {
return Statistics{}
}
stats := Statistics{
Count: len(values),
Min: values[0],
Max: values[0],
}
for _, value := range values {
stats.Sum += value
if value < stats.Min {
stats.Min = value
}
if value > stats.Max {
stats.Max = value
}
}
stats.Average = stats.Sum / float64(stats.Count)
return stats
}#🎯 Functions as Values
#Function Variables
import "math"
func main() {
// 函数可以赋值给变量
var operation func(float64, float64) float64
operation = add_float
fmt.Printf("加法: %.2f\n", operation(3.5, 2.1))
operation = multiply_float
fmt.Printf("乘法: %.2f\n", operation(3.5, 2.1))
// 函数切片
operations := []func(float64, float64) float64{
add_float,
subtract_float,
multiply_float,
divide_float,
}
operationNames := []string{"加法", "减法", "乘法", "除法"}
a, b := 10.0, 3.0
for i, op := range operations {
result := op(a, b)
fmt.Printf("%.1f %s %.1f = %.2f\n", a, operationNames[i], b, result)
}
// 函数映射
calculator := map[string]func(float64, float64) float64{
"+": add_float,
"-": subtract_float,
"*": multiply_float,
"/": divide_float,
"^": math.Pow,
}
fmt.Println("\n计算器演示:")
expressions := []struct {
a, b float64
op string
}{
{10, 5, "+"},
{10, 5, "-"},
{10, 5, "*"},
{10, 5, "/"},
{2, 8, "^"},
}
for _, expr := range expressions {
if fn, exists := calculator[expr.op]; exists {
result := fn(expr.a, expr.b)
fmt.Printf("%.1f %s %.1f = %.2f\n", expr.a, expr.op, expr.b, result)
}
}
}
func add_float(a, b float64) float64 { return a + b }
func subtract_float(a, b float64) float64 { return a - b }
func multiply_float(a, b float64) float64 { return a * b }
func divide_float(a, b float64) float64 { return a / b }#Higher-Order Functions
func main() {
// 高阶函数:接受函数作为参数
numbers := []int{1, 2, 3, 4, 5}
// 应用不同的变换函数
squared := applyTransform(numbers, square)
fmt.Printf("平方: %v\n", squared)
doubled := applyTransform(numbers, double)
fmt.Printf("翻倍: %v\n", doubled)
cubed := applyTransform(numbers, func(x int) int { return x * x * x })
fmt.Printf("立方: %v\n", cubed)
// 过滤函数
evens := filter(numbers, isEven)
fmt.Printf("偶数: %v\n", evens)
odds := filter(numbers, isOdd)
fmt.Printf("奇数: %v\n", odds)
// 归约函数
sum := reduce(numbers, 0, add_int)
fmt.Printf("总和: %d\n", sum)
product := reduce(numbers, 1, multiply_int)
fmt.Printf("乘积: %d\n", product)
// 复合函数
addThenSquare := compose(square, func(x int) int { return x + 1 })
result := addThenSquare(5) // (5+1)^2 = 36
fmt.Printf("先加1再平方: %d\n", result)
}
// 变换函数:对切片中每个元素应用函数
func applyTransform(slice []int, fn func(int) int) []int {
result := make([]int, len(slice))
for i, v := range slice {
result[i] = fn(v)
}
return result
}
// 过滤函数:根据条件过滤元素
func filter(slice []int, predicate func(int) bool) []int {
var result []int
for _, v := range slice {
if predicate(v) {
result = append(result, v)
}
}
return result
}
// 归约函数:将切片归约为单个值
func reduce(slice []int, initial int, fn func(int, int) int) int {
result := initial
for _, v := range slice {
result = fn(result, v)
}
return result
}
// 函数组合
func compose(f, g func(int) int) func(int) int {
return func(x int) int {
return f(g(x))
}
}
// 辅助函数
func square(x int) int { return x * x }
func double(x int) int { return x * 2 }
func isEven(x int) bool { return x%2 == 0 }
func isOdd(x int) bool { return x%2 != 0 }
func add_int(a, b int) int { return a + b }
func multiply_int(a, b int) int { return a * b }#🔄 Recursive Functions
#Basic Recursion
func main() {
// 阶乘计算
for i := 0; i <= 10; i++ {
fmt.Printf("%d! = %d\n", i, factorial(i))
}
// 斐波那契数列
fmt.Println("\n斐波那契数列:")
for i := 0; i <= 15; i++ {
fmt.Printf("fib(%d) = %d\n", i, fibonacci(i))
}
// 汉诺塔问题
fmt.Println("\n汉诺塔移动步骤 (3个盘子):")
hanoi(3, "A", "C", "B")
}
// 阶乘函数
func factorial(n int) int {
if n <= 1 {
return 1
}
return n * factorial(n-1)
}
// 斐波那契数列
func fibonacci(n int) int {
if n <= 1 {
return n
}
return fibonacci(n-1) + fibonacci(n-2)
}
// 汉诺塔问题
func hanoi(n int, from, to, aux string) {
if n == 1 {
fmt.Printf("将盘子从 %s 移动到 %s\n", from, to)
return
}
hanoi(n-1, from, aux, to)
fmt.Printf("将盘子从 %s 移动到 %s\n", from, to)
hanoi(n-1, aux, to, from)
}#Tail Recursion Optimization
func main() {
// 普通递归 vs 尾递归
fmt.Printf("普通递归阶乘 10! = %d\n", factorial(10))
fmt.Printf("尾递归阶乘 10! = %d\n", factorialTail(10))
// 尾递归斐波那契
fmt.Printf("尾递归斐波那契 fib(15) = %d\n", fibonacciTail(15))
}
// 尾递归阶乘
func factorialTail(n int) int {
return factorialHelper(n, 1)
}
func factorialHelper(n, acc int) int {
if n <= 1 {
return acc
}
return factorialHelper(n-1, n*acc)
}
// 尾递归斐波那契
func fibonacciTail(n int) int {
return fibonacciHelper(n, 0, 1)
}
func fibonacciHelper(n, a, b int) int {
if n == 0 {
return a
}
if n == 1 {
return b
}
return fibonacciHelper(n-1, b, a+b)
}#🎯 Practical Examples
#Math Utility Library
import "math"
// 数学工具包
type MathUtils struct{}
func NewMathUtils() *MathUtils {
return &MathUtils{}
}
func main() {
math := NewMathUtils()
// 几何计算
fmt.Printf("圆形面积 (半径5): %.2f\n", math.CircleArea(5))
fmt.Printf("矩形面积 (5x3): %.2f\n", math.RectangleArea(5, 3))
fmt.Printf("三角形面积 (底5高4): %.2f\n", math.TriangleArea(5, 4))
// 数值计算
fmt.Printf("最大公约数 (48, 18): %d\n", math.GCD(48, 18))
fmt.Printf("最小公倍数 (48, 18): %d\n", math.LCM(48, 18))
fmt.Printf("是否为素数 (17): %t\n", math.IsPrime(17))
fmt.Printf("是否为素数 (18): %t\n", math.IsPrime(18))
// 统计计算
data := []float64{85, 92, 78, 96, 88, 91, 79, 95}
fmt.Printf("平均值: %.2f\n", math.Mean(data))
fmt.Printf("中位数: %.2f\n", math.Median(data))
fmt.Printf("标准差: %.2f\n", math.StandardDeviation(data))
}
// 几何计算函数
func (m *MathUtils) CircleArea(radius float64) float64 {
return math.Pi * radius * radius
}
func (m *MathUtils) RectangleArea(length, width float64) float64 {
return length * width
}
func (m *MathUtils) TriangleArea(base, height float64) float64 {
return 0.5 * base * height
}
// 数论函数
func (m *MathUtils) GCD(a, b int) int {
for b != 0 {
a, b = b, a%b
}
return a
}
func (m *MathUtils) LCM(a, b int) int {
return (a * b) / m.GCD(a, b)
}
func (m *MathUtils) IsPrime(n int) bool {
if n < 2 {
return false
}
if n == 2 {
return true
}
if n%2 == 0 {
return false
}
for i := 3; i*i <= n; i += 2 {
if n%i == 0 {
return false
}
}
return true
}
// 统计函数
func (m *MathUtils) Mean(data []float64) float64 {
if len(data) == 0 {
return 0
}
sum := 0.0
for _, v := range data {
sum += v
}
return sum / float64(len(data))
}
func (m *MathUtils) Median(data []float64) float64 {
if len(data) == 0 {
return 0
}
// 复制并排序数据
sorted := make([]float64, len(data))
copy(sorted, data)
// 简单排序
for i := 0; i < len(sorted)-1; i++ {
for j := i + 1; j < len(sorted); j++ {
if sorted[i] > sorted[j] {
sorted[i], sorted[j] = sorted[j], sorted[i]
}
}
}
n := len(sorted)
if n%2 == 0 {
return (sorted[n/2-1] + sorted[n/2]) / 2
}
return sorted[n/2]
}
func (m *MathUtils) StandardDeviation(data []float64) float64 {
if len(data) <= 1 {
return 0
}
mean := m.Mean(data)
sumSquaredDiff := 0.0
for _, v := range data {
diff := v - mean
sumSquaredDiff += diff * diff
}
variance := sumSquaredDiff / float64(len(data)-1)
return math.Sqrt(variance)
}#🎓 Summary
In this chapter, we explored Go functions in depth:
- ✅ Function basics: declaration, parameters, return values, named return values
- ✅ Variadic parameters: flexible parameter handling
- ✅ Function values: functions as first-class citizens, higher-order functions
- ✅ Recursive functions: recursion principles and tail recursion optimization
- ✅ Practical applications: implementing a math utility library
Functions are a core concept in Go. Mastering their various uses is essential for writing high-quality Go code.
Next, we will learn Advanced Go Functions, including closures, anonymous functions, and other advanced features.
::: tip Function Usage Tips
- Keep functions short and focused on a single responsibility
- Use descriptive function and parameter names
- Leverage multiple return values for error handling
- Consider named return values to improve readability :::