1.3.3 函数定义与调用

1.3.3 函数定义与调用 #

函数是 Go 语言程序的基本构建块,它将代码组织成可重用的模块。Go 语言的函数设计简洁而强大,支持多返回值、命名返回值等特性。本节将详细介绍函数的定义、调用和基本特性。

函数的基本语法 #

1. 函数定义 #

Go 语言函数的基本语法如下:

func 函数名(参数列表) (返回值列表) {
    函数体
}

让我们从简单的例子开始:

package main

import "fmt"

// 无参数无返回值的函数
func sayHello() {
    fmt.Println("Hello, World!")
}

// 有参数无返回值的函数
func greet(name string) {
    fmt.Printf("Hello, %s!\n", name)
}

// 有参数有返回值的函数
func add(a, b int) int {
    return a + b
}

// 多个参数,多个返回值
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("除数不能为零")
    }
    return a / b, nil
}

func main() {
    // 调用无参数函数
    sayHello()

    // 调用有参数函数
    greet("张三")

    // 调用有返回值函数
    sum := add(5, 3)
    fmt.Printf("5 + 3 = %d\n", sum)

    // 调用多返回值函数
    result, err := divide(10, 2)
    if err != nil {
        fmt.Printf("错误: %v\n", err)
    } else {
        fmt.Printf("10 / 2 = %.2f\n", result)
    }

    // 处理除零错误
    result, err = divide(10, 0)
    if err != nil {
        fmt.Printf("错误: %v\n", err)
    } else {
        fmt.Printf("结果: %.2f\n", result)
    }
}

2. 参数传递 #

Go 语言中所有参数都是按值传递的:

package main

import "fmt"

// 基本类型参数传递
func modifyValue(x int) {
    x = 100
    fmt.Printf("函数内 x 的值: %d\n", x)
}

// 切片参数传递
func modifySlice(s []int) {
    s[0] = 999
    fmt.Printf("函数内切片: %v\n", s)
}

// 指针参数传递
func modifyByPointer(x *int) {
    *x = 200
    fmt.Printf("函数内通过指针修改的值: %d\n", *x)
}

// 结构体参数传递
type Person struct {
    Name string
    Age  int
}

func modifyPerson(p Person) {
    p.Name = "修改后的名字"
    p.Age = 100
    fmt.Printf("函数内结构体: %+v\n", p)
}

func modifyPersonByPointer(p *Person) {
    p.Name = "通过指针修改的名字"
    p.Age = 200
    fmt.Printf("函数内通过指针修改的结构体: %+v\n", *p)
}

func main() {
    // 基本类型参数传递
    fmt.Println("=== 基本类型参数传递 ===")
    num := 10
    fmt.Printf("调用前 num 的值: %d\n", num)
    modifyValue(num)
    fmt.Printf("调用后 num 的值: %d\n", num)

    // 切片参数传递
    fmt.Println("\n=== 切片参数传递 ===")
    slice := []int{1, 2, 3, 4, 5}
    fmt.Printf("调用前切片: %v\n", slice)
    modifySlice(slice)
    fmt.Printf("调用后切片: %v\n", slice)

    // 指针参数传递
    fmt.Println("\n=== 指针参数传递 ===")
    value := 50
    fmt.Printf("调用前 value 的值: %d\n", value)
    modifyByPointer(&value)
    fmt.Printf("调用后 value 的值: %d\n", value)

    // 结构体参数传递
    fmt.Println("\n=== 结构体参数传递 ===")
    person := Person{Name: "张三", Age: 25}
    fmt.Printf("调用前结构体: %+v\n", person)
    modifyPerson(person)
    fmt.Printf("调用后结构体: %+v\n", person)

    // 结构体指针参数传递
    fmt.Println("\n=== 结构体指针参数传递 ===")
    fmt.Printf("调用前结构体: %+v\n", person)
    modifyPersonByPointer(&person)
    fmt.Printf("调用后结构体: %+v\n", person)
}

3. 返回值 #

Go 语言支持多种返回值形式:

package main

import (
    "fmt"
    "math"
    "strconv"
)

// 单个返回值
func square(x float64) float64 {
    return x * x
}

// 多个返回值
func divmod(a, b int) (int, int) {
    return a / b, a % b
}

// 命名返回值
func rectangleArea(length, width float64) (area float64) {
    area = length * width
    return // 裸返回
}

// 命名返回值的复杂示例
func calculateStats(numbers []float64) (sum, avg, min, max float64, count int) {
    if len(numbers) == 0 {
        return // 所有返回值都是零值
    }

    count = len(numbers)
    sum = numbers[0]
    min = numbers[0]
    max = numbers[0]

    for _, num := range numbers {
        sum += num
        if num < min {
            min = num
        }
        if num > max {
            max = num
        }
    }

    avg = sum / float64(count)
    return // 裸返回
}

// 返回函数类型
func getOperation(op string) func(int, int) int {
    switch op {
    case "+":
        return func(a, b int) int { return a + b }
    case "-":
        return func(a, b int) int { return a - b }
    case "*":
        return func(a, b int) int { return a * b }
    case "/":
        return func(a, b int) int { return a / b }
    default:
        return nil
    }
}

// 错误处理模式
func parseInteger(s string) (int, error) {
    value, err := strconv.Atoi(s)
    if err != nil {
        return 0, fmt.Errorf("无法解析整数 '%s': %v", s, err)
    }
    return value, nil
}

func main() {
    // 单个返回值
    fmt.Printf("5 的平方: %.2f\n", square(5))

    // 多个返回值
    quotient, remainder := divmod(17, 5)
    fmt.Printf("17 除以 5: 商=%d, 余数=%d\n", quotient, remainder)

    // 忽略某个返回值
    q, _ := divmod(20, 3)
    fmt.Printf("20 除以 3 的商: %d\n", q)

    // 命名返回值
    area := rectangleArea(5.5, 3.2)
    fmt.Printf("矩形面积: %.2f\n", area)

    // 复杂的命名返回值
    numbers := []float64{1.5, 2.8, 0.5, 4.2, 3.1, 2.9, 1.8}
    sum, avg, min, max, count := calculateStats(numbers)
    fmt.Printf("统计结果: 总和=%.2f, 平均=%.2f, 最小=%.2f, 最大=%.2f, 数量=%d\n",
               sum, avg, min, max, count)

    // 返回函数类型
    addFunc := getOperation("+")
    if addFunc != nil {
        result := addFunc(10, 5)
        fmt.Printf("10 + 5 = %d\n", result)
    }

    // 错误处理
    if value, err := parseInteger("123"); err != nil {
        fmt.Printf("解析错误: %v\n", err)
    } else {
        fmt.Printf("解析成功: %d\n", value)
    }

    if value, err := parseInteger("abc"); err != nil {
        fmt.Printf("解析错误: %v\n", err)
    } else {
        fmt.Printf("解析成功: %d\n", value)
    }
}

函数的高级特性 #

1. 可变参数 #

Go 语言支持可变参数函数:

package main

import "fmt"

// 可变参数函数
func sum(numbers ...int) int {
    total := 0
    for _, num := range numbers {
        total += num
    }
    return total
}

// 混合参数:固定参数 + 可变参数
func printf(format string, args ...interface{}) {
    fmt.Printf(format, args...)
}

// 字符串连接函数
func concat(separator string, strings ...string) string {
    if len(strings) == 0 {
        return ""
    }

    result := strings[0]
    for i := 1; i < len(strings); i++ {
        result += separator + strings[i]
    }
    return result
}

// 查找最大值
func max(first int, others ...int) int {
    maximum := first
    for _, value := range others {
        if value > maximum {
            maximum = value
        }
    }
    return maximum
}

// 格式化输出多个值
func printValues(prefix string, values ...interface{}) {
    fmt.Print(prefix)
    for i, value := range values {
        if i > 0 {
            fmt.Print(", ")
        }
        fmt.Printf("%v", value)
    }
    fmt.Println()
}

func main() {
    // 调用可变参数函数
    fmt.Printf("sum() = %d\n", sum())
    fmt.Printf("sum(1) = %d\n", sum(1))
    fmt.Printf("sum(1, 2, 3) = %d\n", sum(1, 2, 3))
    fmt.Printf("sum(1, 2, 3, 4, 5) = %d\n", sum(1, 2, 3, 4, 5))

    // 传递切片给可变参数函数
    numbers := []int{10, 20, 30, 40, 50}
    fmt.Printf("sum(numbers...) = %d\n", sum(numbers...))

    // 使用自定义 printf
    printf("姓名: %s, 年龄: %d, 身高: %.1f\n", "张三", 25, 175.5)

    // 字符串连接
    result := concat(" | ", "苹果", "香蕉", "橙子", "葡萄")
    fmt.Printf("连接结果: %s\n", result)

    // 查找最大值
    maximum := max(5, 2, 8, 1, 9, 3)
    fmt.Printf("最大值: %d\n", maximum)

    // 格式化输出
    printValues("数字: ", 1, 2, 3, 4, 5)
    printValues("混合: ", "hello", 42, 3.14, true)
}

2. 函数作为值 #

在 Go 语言中,函数是一等公民,可以作为值传递:

package main

import (
    "fmt"
    "math"
)

// 定义函数类型
type MathOperation func(float64, float64) float64
type Predicate func(int) bool

// 基本数学运算函数
func add(a, b float64) float64 {
    return a + b
}

func subtract(a, b float64) float64 {
    return a - b
}

func multiply(a, b float64) float64 {
    return a * b
}

func divide(a, b float64) float64 {
    if b != 0 {
        return a / b
    }
    return math.NaN()
}

// 应用运算函数
func applyOperation(a, b float64, op MathOperation) float64 {
    return op(a, b)
}

// 创建运算器
func createCalculator() map[string]MathOperation {
    return map[string]MathOperation{
        "+": add,
        "-": subtract,
        "*": multiply,
        "/": divide,
    }
}

// 过滤函数
func filter(numbers []int, predicate Predicate) []int {
    var result []int
    for _, num := range numbers {
        if predicate(num) {
            result = append(result, num)
        }
    }
    return result
}

// 映射函数
func mapInts(numbers []int, mapper func(int) int) []int {
    result := make([]int, len(numbers))
    for i, num := range numbers {
        result[i] = mapper(num)
    }
    return result
}

// 归约函数
func reduce(numbers []int, initial int, reducer func(int, int) int) int {
    result := initial
    for _, num := range numbers {
        result = reducer(result, num)
    }
    return result
}

func main() {
    // 函数作为变量
    var operation MathOperation = add
    result := operation(5, 3)
    fmt.Printf("5 + 3 = %.2f\n", result)

    // 函数作为参数
    fmt.Printf("应用加法: %.2f\n", applyOperation(10, 5, add))
    fmt.Printf("应用乘法: %.2f\n", applyOperation(10, 5, multiply))

    // 使用函数映射
    calculator := createCalculator()
    fmt.Printf("使用计算器 +: %.2f\n", calculator["+"](8, 2))
    fmt.Printf("使用计算器 *: %.2f\n", calculator["*"](8, 2))

    // 函数式编程示例
    numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

    // 过滤偶数
    evenNumbers := filter(numbers, func(n int) bool {
        return n%2 == 0
    })
    fmt.Printf("偶数: %v\n", evenNumbers)

    // 过滤大于5的数
    greaterThanFive := filter(numbers, func(n int) bool {
        return n > 5
    })
    fmt.Printf("大于5的数: %v\n", greaterThanFive)

    // 映射:每个数乘以2
    doubled := mapInts(numbers, func(n int) int {
        return n * 2
    })
    fmt.Printf("每个数乘以2: %v\n", doubled)

    // 映射:每个数的平方
    squared := mapInts(numbers, func(n int) int {
        return n * n
    })
    fmt.Printf("每个数的平方: %v\n", squared)

    // 归约:求和
    sum := reduce(numbers, 0, func(acc, n int) int {
        return acc + n
    })
    fmt.Printf("求和: %d\n", sum)

    // 归约:求积
    product := reduce(numbers, 1, func(acc, n int) int {
        return acc * n
    })
    fmt.Printf("求积: %d\n", product)
}

3. 匿名函数和闭包 #

package main

import "fmt"

// 返回闭包的函数
func createCounter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

// 创建累加器
func createAccumulator(initial int) func(int) int {
    sum := initial
    return func(value int) int {
        sum += value
        return sum
    }
}

// 创建乘法器
func createMultiplier(factor int) func(int) int {
    return func(value int) int {
        return value * factor
    }
}

// 函数工厂
func createValidator(min, max int) func(int) bool {
    return func(value int) bool {
        return value >= min && value <= max
    }
}

func main() {
    // 匿名函数直接调用
    result := func(a, b int) int {
        return a + b
    }(5, 3)
    fmt.Printf("匿名函数结果: %d\n", result)

    // 将匿名函数赋值给变量
    square := func(x int) int {
        return x * x
    }
    fmt.Printf("5 的平方: %d\n", square(5))

    // 闭包示例:计数器
    counter1 := createCounter()
    counter2 := createCounter()

    fmt.Printf("counter1: %d\n", counter1()) // 1
    fmt.Printf("counter1: %d\n", counter1()) // 2
    fmt.Printf("counter2: %d\n", counter2()) // 1
    fmt.Printf("counter1: %d\n", counter1()) // 3
    fmt.Printf("counter2: %d\n", counter2()) // 2

    // 闭包示例:累加器
    acc1 := createAccumulator(0)
    acc2 := createAccumulator(100)

    fmt.Printf("acc1 加 5: %d\n", acc1(5))   // 5
    fmt.Printf("acc1 加 10: %d\n", acc1(10)) // 15
    fmt.Printf("acc2 加 5: %d\n", acc2(5))   // 105
    fmt.Printf("acc1 加 3: %d\n", acc1(3))   // 18

    // 闭包示例:乘法器
    double := createMultiplier(2)
    triple := createMultiplier(3)

    fmt.Printf("5 的两倍: %d\n", double(5))  // 10
    fmt.Printf("5 的三倍: %d\n", triple(5))  // 15

    // 闭包示例:验证器
    ageValidator := createValidator(18, 65)
    scoreValidator := createValidator(0, 100)

    ages := []int{16, 25, 70, 30}
    scores := []int{85, 105, -5, 92}

    fmt.Println("年龄验证:")
    for _, age := range ages {
        fmt.Printf("年龄 %d 有效: %t\n", age, ageValidator(age))
    }

    fmt.Println("分数验证:")
    for _, score := range scores {
        fmt.Printf("分数 %d 有效: %t\n", score, scoreValidator(score))
    }

    // 在循环中使用闭包
    var functions []func() int

    // 错误的做法(常见陷阱)
    for i := 0; i < 3; i++ {
        functions = append(functions, func() int {
            return i // 这里会捕获循环变量 i 的引用
        })
    }

    fmt.Println("错误的闭包使用:")
    for j, f := range functions {
        fmt.Printf("函数 %d 返回: %d\n", j, f()) // 都会返回 3
    }

    // 正确的做法
    functions = nil
    for i := 0; i < 3; i++ {
        i := i // 创建局部变量
        functions = append(functions, func() int {
            return i
        })
    }

    fmt.Println("正确的闭包使用:")
    for j, f := range functions {
        fmt.Printf("函数 %d 返回: %d\n", j, f())
    }
}

实际应用示例 #

1. 数学计算库 #

package main

import (
    "fmt"
    "math"
)

// 数学运算库
type MathLib struct{}

// 基本运算
func (m MathLib) Add(a, b float64) float64 {
    return a + b
}

func (m MathLib) Subtract(a, b float64) float64 {
    return a - b
}

func (m MathLib) Multiply(a, b float64) float64 {
    return a * b
}

func (m MathLib) Divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("除数不能为零")
    }
    return a / b, nil
}

// 高级运算
func (m MathLib) Power(base, exponent float64) float64 {
    return math.Pow(base, exponent)
}

func (m MathLib) Sqrt(x float64) (float64, error) {
    if x < 0 {
        return 0, fmt.Errorf("负数没有实数平方根")
    }
    return math.Sqrt(x), nil
}

func (m MathLib) Factorial(n int) (int64, error) {
    if n < 0 {
        return 0, fmt.Errorf("负数没有阶乘")
    }
    if n > 20 {
        return 0, fmt.Errorf("数字太大,会导致溢出")
    }

    result := int64(1)
    for i := 2; i <= n; i++ {
        result *= int64(i)
    }
    return result, nil
}

// 统计函数
func (m MathLib) Mean(numbers []float64) (float64, error) {
    if len(numbers) == 0 {
        return 0, fmt.Errorf("空数组没有平均值")
    }

    sum := 0.0
    for _, num := range numbers {
        sum += num
    }
    return sum / float64(len(numbers)), nil
}

func (m MathLib) Median(numbers []float64) (float64, error) {
    if len(numbers) == 0 {
        return 0, fmt.Errorf("空数组没有中位数")
    }

    // 复制并排序
    sorted := make([]float64, len(numbers))
    copy(sorted, numbers)

    // 简单的冒泡排序
    for i := 0; i < len(sorted)-1; i++ {
        for j := 0; j < len(sorted)-i-1; j++ {
            if sorted[j] > sorted[j+1] {
                sorted[j], sorted[j+1] = sorted[j+1], sorted[j]
            }
        }
    }

    n := len(sorted)
    if n%2 == 0 {
        return (sorted[n/2-1] + sorted[n/2]) / 2, nil
    }
    return sorted[n/2], nil
}

func (m MathLib) StandardDeviation(numbers []float64) (float64, error) {
    if len(numbers) == 0 {
        return 0, fmt.Errorf("空数组没有标准差")
    }

    mean, _ := m.Mean(numbers)

    sumSquaredDiff := 0.0
    for _, num := range numbers {
        diff := num - mean
        sumSquaredDiff += diff * diff
    }

    variance := sumSquaredDiff / float64(len(numbers))
    return math.Sqrt(variance), nil
}

func main() {
    math := MathLib{}

    // 基本运算测试
    fmt.Println("=== 基本运算 ===")
    fmt.Printf("10 + 5 = %.2f\n", math.Add(10, 5))
    fmt.Printf("10 - 5 = %.2f\n", math.Subtract(10, 5))
    fmt.Printf("10 * 5 = %.2f\n", math.Multiply(10, 5))

    if result, err := math.Divide(10, 5); err != nil {
        fmt.Printf("除法错误: %v\n", err)
    } else {
        fmt.Printf("10 / 5 = %.2f\n", result)
    }

    // 高级运算测试
    fmt.Println("\n=== 高级运算 ===")
    fmt.Printf("2^10 = %.0f\n", math.Power(2, 10))

    if result, err := math.Sqrt(16); err != nil {
        fmt.Printf("平方根错误: %v\n", err)
    } else {
        fmt.Printf("√16 = %.2f\n", result)
    }

    if result, err := math.Factorial(5); err != nil {
        fmt.Printf("阶乘错误: %v\n", err)
    } else {
        fmt.Printf("5! = %d\n", result)
    }

    // 统计函数测试
    fmt.Println("\n=== 统计函数 ===")
    data := []float64{1.5, 2.3, 3.7, 2.1, 4.2, 1.8, 3.4, 2.9}

    if mean, err := math.Mean(data); err != nil {
        fmt.Printf("平均值错误: %v\n", err)
    } else {
        fmt.Printf("平均值: %.2f\n", mean)
    }

    if median, err := math.Median(data); err != nil {
        fmt.Printf("中位数错误: %v\n", err)
    } else {
        fmt.Printf("中位数: %.2f\n", median)
    }

    if stdDev, err := math.StandardDeviation(data); err != nil {
        fmt.Printf("标准差错误: %v\n", err)
    } else {
        fmt.Printf("标准差: %.2f\n", stdDev)
    }
}

2. 字符串处理工具 #

package main

import (
    "fmt"
    "strings"
    "unicode"
)

// 字符串工具函数集合

// 反转字符串
func reverseString(s string) string {
    runes := []rune(s)
    for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
        runes[i], runes[j] = runes[j], runes[i]
    }
    return string(runes)
}

// 检查是否为回文
func isPalindrome(s string) bool {
    // 转换为小写并移除非字母数字字符
    cleaned := ""
    for _, r := range strings.ToLower(s) {
        if unicode.IsLetter(r) || unicode.IsDigit(r) {
            cleaned += string(r)
        }
    }

    return cleaned == reverseString(cleaned)
}

// 统计单词数量
func wordCount(text string) map[string]int {
    words := strings.Fields(strings.ToLower(text))
    count := make(map[string]int)

    for _, word := range words {
        // 移除标点符号
        cleaned := ""
        for _, r := range word {
            if unicode.IsLetter(r) {
                cleaned += string(r)
            }
        }
        if cleaned != "" {
            count[cleaned]++
        }
    }

    return count
}

// 首字母大写
func capitalizeWords(s string) string {
    words := strings.Fields(s)
    for i, word := range words {
        if len(word) > 0 {
            words[i] = strings.ToUpper(string(word[0])) + strings.ToLower(word[1:])
        }
    }
    return strings.Join(words, " ")
}

// 移除重复字符
func removeDuplicateChars(s string) string {
    seen := make(map[rune]bool)
    result := ""

    for _, r := range s {
        if !seen[r] {
            seen[r] = true
            result += string(r)
        }
    }

    return result
}

// 查找最长公共前缀
func longestCommonPrefix(strs []string) string {
    if len(strs) == 0 {
        return ""
    }

    prefix := strs[0]
    for _, str := range strs[1:] {
        for !strings.HasPrefix(str, prefix) {
            prefix = prefix[:len(prefix)-1]
            if prefix == "" {
                return ""
            }
        }
    }

    return prefix
}

// 字符串压缩(简单版本)
func compressString(s string) string {
    if len(s) == 0 {
        return s
    }

    compressed := ""
    count := 1
    current := rune(s[0])

    for _, r := range s[1:] {
        if r == current {
            count++
        } else {
            compressed += string(current) + fmt.Sprintf("%d", count)
            current = r
            count = 1
        }
    }
    compressed += string(current) + fmt.Sprintf("%d", count)

    if len(compressed) < len(s) {
        return compressed
    }
    return s
}

// 验证括号匹配
func isValidParentheses(s string) bool {
    stack := []rune{}
    pairs := map[rune]rune{
        ')': '(',
        '}': '{',
        ']': '[',
    }

    for _, r := range s {
        switch r {
        case '(', '{', '[':
            stack = append(stack, r)
        case ')', '}', ']':
            if len(stack) == 0 || stack[len(stack)-1] != pairs[r] {
                return false
            }
            stack = stack[:len(stack)-1]
        }
    }

    return len(stack) == 0
}

func main() {
    // 测试字符串工具函数

    // 反转字符串
    fmt.Println("=== 字符串反转 ===")
    text := "Hello, 世界!"
    fmt.Printf("原字符串: %s\n", text)
    fmt.Printf("反转后: %s\n", reverseString(text))

    // 回文检查
    fmt.Println("\n=== 回文检查 ===")
    palindromes := []string{
        "A man a plan a canal Panama",
        "race a car",
        "hello",
        "Madam",
        "12321",
    }

    for _, s := range palindromes {
        fmt.Printf("'%s' 是回文: %t\n", s, isPalindrome(s))
    }

    // 单词统计
    fmt.Println("\n=== 单词统计 ===")
    article := "Go is a programming language. Go is simple and efficient. Programming with Go is fun."
    wordCounts := wordCount(article)
    fmt.Printf("文章: %s\n", article)
    fmt.Println("单词统计:")
    for word, count := range wordCounts {
        fmt.Printf("  %s: %d\n", word, count)
    }

    // 首字母大写
    fmt.Println("\n=== 首字母大写 ===")
    sentence := "hello world from go programming"
    fmt.Printf("原句子: %s\n", sentence)
    fmt.Printf("首字母大写: %s\n", capitalizeWords(sentence))

    // 移除重复字符
    fmt.Println("\n=== 移除重复字符 ===")
    duplicateStr := "programming"
    fmt.Printf("原字符串: %s\n", duplicateStr)
    fmt.Printf("移除重复后: %s\n", removeDuplicateChars(duplicateStr))

    // 最长公共前缀
    fmt.Println("\n=== 最长公共前缀 ===")
    strings1 := []string{"flower", "flow", "flight"}
    strings2 := []string{"dog", "racecar", "car"}
    fmt.Printf("字符串组1: %v\n", strings1)
    fmt.Printf("最长公共前缀: '%s'\n", longestCommonPrefix(strings1))
    fmt.Printf("字符串组2: %v\n", strings2)
    fmt.Printf("最长公共前缀: '%s'\n", longestCommonPrefix(strings2))

    // 字符串压缩
    fmt.Println("\n=== 字符串压缩 ===")
    compressTests := []string{"aabcccccaaa", "abcdef", "aabbcc"}
    for _, s := range compressTests {
        compressed := compressString(s)
        fmt.Printf("'%s' -> '%s'\n", s, compressed)
    }

    // 括号匹配验证
    fmt.Println("\n=== 括号匹配验证 ===")
    parenthesesTests := []string{
        "()",
        "()[]{}",
        "(]",
        "([)]",
        "{[]}",
        "((()))",
        "(((",
    }

    for _, s := range parenthesesTests {
        fmt.Printf("'%s' 括号匹配: %t\n", s, isValidParentheses(s))
    }
}

小结 #

本节详细介绍了 Go 语言的函数定义与调用,主要内容包括:

函数基础 #

  • 函数语法:func 关键字、参数列表、返回值列表
  • 参数传递:值传递、指针传递、切片传递
  • 返回值:单返回值、多返回值、命名返回值

高级特性 #

  • 可变参数:使用 ... 语法接受不定数量参数
  • 函数作为值:函数类型、函数变量、函数参数
  • 匿名函数:内联函数定义和调用
  • 闭包:捕获外部变量的匿名函数

实际应用 #

  • 数学计算库:封装常用数学运算
  • 字符串处理:实现各种字符串操作工具
  • 函数式编程:filter、map、reduce 等高阶函数

最佳实践 #

  • 合理使用多返回值处理错误
  • 利用闭包实现状态封装
  • 使用函数类型提高代码灵活性
  • 注意闭包中变量捕获的陷阱

掌握函数的定义和调用是 Go 语言编程的核心技能,为后续学习函数高级特性和面向对象编程奠定了基础。


练习题:

  1. 编写一个计算器程序,支持基本的四则运算和错误处理
  2. 实现一个字符串工具库,包含常用的字符串操作函数
  3. 创建一个数学统计库,计算平均值、中位数、标准差等
  4. 编写函数式编程工具,实现 filter、map、reduce 功能
  5. 实现一个简单的表达式求值器,支持基本的数学表达式