Go语言函数:从基础到高级应用实践

一、函数定义基础语法

// 基础函数定义模板
func functionName(参数列表) 返回值类型 {
    // 函数体
}

// 带参数的函数示例
func add(x int, y int) int {
    return x + y
}

// 参数类型简写(相同类型参数)
func multiply(a, b int) int {
    return a * b
}

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

关键知识点:

  1. 参数列表支持类型后置语法
  2. 返回值类型可以是单个或多个
  3. 支持命名返回值(后面详解)
  4. 函数首字母大小写决定访问权限

二、函数调用方式详解

2.1 基本调用方式

sum := add(3, 5)
fmt.Println(sum) // 输出8

printHello() // 直接调用无返回值函数

2.2 忽略返回值

// 使用空白标识符忽略返回值
_, err := os.Open("file.txt")
if err != nil {
    log.Fatal(err)
}

2.3 链式调用

// 连续调用示例
strings.NewReader("hello").Read(make([]byte, 5))

三、多返回值深度解析

3.1 基本多返回值

func swap(a, b string) (string, string) {
    return b, a
}

x, y := swap("hello", "world")

3.2 命名返回值

func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return // 裸返回
}

a, b := split(100)

3.3 错误处理模式

func OpenFile(path string) (*os.File, error) {
    file, err := os.Open(path)
    if err != nil {
        return nil, err
    }
    return file, nil
}

四、可变参数函数

func sum(nums ...int) int {
    total := 0
    for _, num := range nums {
        total += num
    }
    return total
}

// 使用示例
fmt.Println(sum(1,2,3))       // 6
fmt.Println(sum([]int{4,5,6}...)) // 切片展开

高级用法:

func logger(prefix string, values ...interface{}) {
    fmt.Printf("[%s] %v\n", prefix, values)
}

logger("DEBUG", "user login", 200, time.Now())

五、匿名函数与闭包

5.1 匿名函数定义

// 立即执行函数
func() {
    fmt.Println("立即执行匿名函数")
}()

// 赋值给变量
square := func(x int) int {
    return x * x
}
fmt.Println(square(5)) // 25

5.2 闭包实践

// 累加器生成器
func adder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}

a := adder()
fmt.Println(a(1))  // 1
fmt.Println(a(2))  // 3
fmt.Println(a(10)) // 13

实际应用场景:

  1. 中间件链
  2. 状态封装
  3. 延迟计算
  4. 并发安全访问

六、错误处理最佳实践

6.1 错误处理模式

func ReadConfig(path string) (Config, error) {
    file, err := os.Open(path)
    if err != nil {
        return Config{}, fmt.Errorf("打开配置文件失败: %w", err)
    }
    defer file.Close()

    // 解析配置...
    return config, nil
}

6.2 自定义错误类型

type APIError struct {
    Code    int
    Message string
    Details interface{}
}

func (e *APIError) Error() string {
    return fmt.Sprintf("%d: %s", e.Code, e.Message)
}

func NewAPIError(code int, msg string) *APIError {
    return &APIError{
        Code:    code,
        Message: msg,
    }
}

6.3 panic和recover

func safeDivision(a, b int) (result int, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("运行时错误: %v", r)
        }
    }()
    
    if b == 0 {
        panic("除零错误")
    }
    return a / b, nil
}

七、高阶函数应用

7.1 函数作为参数

func filter(numbers []int, condition func(int) bool) []int {
    var result []int
    for _, n := range numbers {
        if condition(n) {
            result = append(result, n)
        }
    }
    return result
}

// 使用示例
numbers := []int{1,2,3,4,5}
evens := filter(numbers, func(n int) bool {
    return n%2 == 0
})

7.2 函数作为返回值

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

double := makeMultiplier(2)
triple := makeMultiplier(3)
fmt.Println(double(5))  // 10
fmt.Println(triple(5))  // 15

八、性能优化技巧

8.1 避免闭包滥用

// 不推荐写法(频繁创建闭包)
func process(data []int) {
    for _, v := range data {
        go func() {
            fmt.Println(v) // 闭包捕获循环变量问题
        }()
    }
}

// 推荐写法
func processOptimized(data []int) {
    for _, v := range data {
        go func(val int) {
            fmt.Println(val)
        }(v)
    }
}

8.2 内联优化

// 简单函数会被编译器自动内联
func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

// 调用处会被优化为直接比较操作
result := max(x, y)

九、测试驱动开发示例

// math_test.go
func TestAdd(t *testing.T) {
    testCases := []struct {
        a, b int
        want int
    }{
        {2, 3, 5},
        {-1, 1, 0},
        {0, 0, 0},
    }

    for _, tc := range testCases {
        got := add(tc.a, tc.b)
        if got != tc.want {
            t.Errorf("add(%d, %d) = %d; want %d", tc.a, tc.b, got, tc.want)
        }
    }
}

十、实战项目案例:中间件实现

type Middleware func(http.HandlerFunc) http.HandlerFunc

func Logger() Middleware {
    return func(next http.HandlerFunc) http.HandlerFunc {
        return func(w http.ResponseWriter, r *http.Request) {
            start := time.Now()
            defer func() {
                log.Printf(
                    "%s %s %v",
                    r.Method,
                    r.URL.Path,
                    time.Since(start),
                )
            }()
            next(w, r)
        }
    }
}

func Chain(f http.HandlerFunc, middlewares ...Middleware) http.HandlerFunc {
    for _, m := range middlewares {
        f = m(f)
    }
    return f
}

// 使用示例
func main() {
    handler := func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello World"))
    }
    
    http.HandleFunc("/", Chain(handler, Logger()))
    http.ListenAndServe(":8080", nil)
}
正文到此结束
评论插件初始化中...
Loading...