4.1 Go 函数基础学习笔记

1. 函数定义 — 基本语法

Go 函数用 func 关键字定义,最简单的形式:无参数、无返回值:

package main

import "fmt"

// greet 函数:无参数、无返回值
func greet() {
    fmt.Println("Hello from a function!")
}

func main() {
    fmt.Println("This runs before the function call")
    greet()
    fmt.Println("This runs after the function call")
}

执行结果:

This runs before the function call
Hello from a function!
This runs after the function call

要点

  • func greet()func 关键字 + 函数名 + 参数列表 + 返回类型
  • 无参数时写空括号 (),无返回值时省略返回类型
  • 函数调用:greet() — 直接用函数名加括号
  • 执行顺序:main 中代码按顺序执行,greet() 在两行 Println 之间被调用
  • 函数定义必须在 main() 之前(或同级),Go 不支持函数嵌套定义(不支持在函数内定义函数,但支持匿名函数)

2. 函数参数 — 传入数据

函数通过参数接收外部数据,参数在函数内部作为局部变量使用:

package main

import "fmt"

// 单个参数
func greetPerson(name string) {
    fmt.Println("Hello, " + name + "!")
}

// 多个参数(各自指定类型)
func add(a int, b int) {
    result := a + b
    fmt.Println("The sum is:", result)
}

func main() {
    greetPerson("Alice")
    greetPerson("Bob")
    add(5, 3)
    add(10, 7)
}

执行结果:

Hello, Alice!
Hello, Bob!
The sum is: 8
The sum is: 17

要点

  • func greetPerson(name string) — 一个 string 参数
  • func add(a int, b int) — 两个 int 参数,各自声明类型
  • 连续同类型参数可省略前面的类型声明:func add(a, b int) 等价于 func add(a int, b int)
  • 参数是值传递:函数收到的是值的拷贝,修改参数不影响原值
  • 字符串拼接:"Hello, " + name + "!" — Go 用 + 拼接字符串

3. 返回值 — 函数输出数据

函数通过 return 返回结果给调用者,Go 支持多返回值:

package main

import "fmt"

// 单个返回值
func double(x int) int {
    return x * 2
}

// 单个返回值(string)
func getGreeting(name string) string {
    return "Hello, " + name + "!"
}

// 多返回值 — 返回结果 + 成功标志
func divide(a, b float64) (float64, bool) {
    if b == 0 {
        return 0.0, false
    }
    return a / b, true
}

func main() {
    result := double(5)
    fmt.Println("Double of 5 is:", result)

    greeting := getGreeting("World")
    fmt.Println(greeting)

    quotient, success := divide(10.0, 2.0)
    fmt.Println("10.0 / 2.0 =", quotient, "Success:", success)

    quotient2, success2 := divide(10.0, 0.0)
    fmt.Println("10.0 / 0.0 =", quotient2, "Success:", success2)
}

执行结果:

Double of 5 is: 10
Hello, World!
10.0 / 2.0 = 5 Success: true
10.0 / 0.0 = 0 Success: false

要点

  • 返回类型写在参数列表后面:func double(x int) int — 最后的 int 是返回类型
  • 多返回值用括号包裹:(float64, bool) — 返回两个值
  • return a / b, true — 同时返回两个值,用逗号分隔
  • 调用方用多重赋值接收:quotient, success := divide(10.0, 2.0)
  • 多返回值是 Go 的核心特性,最常见的用法是 (result, error) 模式:
    func readFile(path string) (string, error) { ... }
    content, err := readFile("data.txt")
    if err != nil { // 处理错误 }
    
  • 如果只想接收其中一个返回值,用 _ 忽略:quotient, _ := divide(10.0, 2.0)

4. 命名返回值 — 裸返回(naked return)

返回值可以命名,命名后函数内直接赋值,return 不需要指定值:

package main

import "fmt"

// 命名返回值:area 和 perimeter
func calculateArea(width, height float64) (area, perimeter float64) {
    area = width * height
    perimeter = 2 * (width + height)
    return // naked return — 自动返回 area 和 perimeter
}

// 命名返回值:first 和 second
func swapStrings(a, b string) (first, second string) {
    first = b
    second = a
    return // naked return — 自动返回 first 和 second
}

func main() {
    area, perimeter := calculateArea(5.0, 3.0)
    fmt.Println("Area:", area, "Perimeter:", perimeter)

    first, second := swapStrings("hello", "world")
    fmt.Println("First:", first, "Second:", second)
}

执行结果:

Area: 15 Perimeter: 16
First: world Second: hello

要点

  • (area, perimeter float64) — 返回值命名,在函数内作为局部变量直接使用
  • 命名后 area = width * height — 直接赋值,不需要 return width * height
  • return — 裸返回,自动返回命名变量的当前值(不需要写 return area, perimeter
  • 调用方仍用多重赋值接收:area, perimeter := calculateArea(5.0, 3.0)
  • 裸返回适合短函数;长函数推荐显式 return 值,避免遗忘赋值导致返回零值
  • 命名返回值的好处:代码自文档化,calculateArea(width, height float64) (area, perimeter float64) 直接告诉读者返回的是什么
  • 命名返回值的另一个用途:在 defer 中修改返回值(见 panic/recover 知识点中的 result = 0

5. 函数类型 — 函数作为变量和参数

函数在 Go 中是一等公民(first-class citizen),可以赋值给变量、作为参数传递:

package main

import "fmt"

func add(a, b int) int {
    return a + b
}

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

// operation 参数是一个函数类型
func operate(a, b int, operation func(int, int) int) int {
    return operation(a, b)
}

func main() {
    // 函数赋值给变量
    var mathFunc func(int, int) int = add
    result1 := mathFunc(5, 3)
    fmt.Println("mathFunc(5, 3) with add:", result1)

    // 变量可以换绑另一个函数
    mathFunc = multiply
    result2 := mathFunc(5, 3)
    fmt.Println("mathFunc(5, 3) with multiply:", result2)

    // 函数作为参数传递
    result3 := operate(10, 4, add)
    fmt.Println("operate(10, 4, add):", result3)

    result4 := operate(10, 4, multiply)
    fmt.Println("operate(10, 4, multiply):", result4)
}

执行结果:

mathFunc(5, 3) with add: 8
mathFunc(5, 3) with multiply: 15
operate(10, 4, add): 14
operate(10, 4, multiply): 40

要点

  • 函数类型签名:func(int, int) int — 描述"接收两个 int、返回一个 int"的函数
  • var mathFunc func(int, int) int = add — 将 add 函数赋值给 mathFunc 变量
  • 调用 mathFunc(5, 3) 和直接调用 add(5, 3) 效果相同(输出 8)
  • mathFunc = multiply — 变量可以重新绑定为另一个函数,调用后输出 15(5*3)
  • operate(a, b int, operation func(int, int) int) — 函数作为参数!
    • operation 参数的类型是 func(int, int) int,传入 addmultiply
    • operate 内部调用 operation(a, b),根据传入的函数执行不同运算
  • 函数是一等公民:可以赋值给变量、作为参数传递、作为返回值(闭包就是返回函数)
  • 这使得 Go 支持策略模式:同一个 operate 函数,通过传入不同运算函数实现不同行为
  • 实际场景:排序时传入比较函数、HTTP 路由传入处理函数等

知识点总结

知识点 关键概念
函数定义 func name() { ... },无参数无返回值的基本形式
函数参数 值传递,连续同类型可省略前面类型声明 a, b int
返回值 单返回值、多返回值 (float64, bool),Go 核心模式 (result, error)
命名返回值 (area, perimeter float64),裸 return,defer 中可修改返回值
函数类型 函数是一等公民,可赋值给变量、作为参数、作为返回值
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容