Go 函数
函数用 func 声明,是 Go 程序的基本组成单元。本节介绍定义、参数与返回值、多返回值、可变参数、指针传参、匿名函数、闭包与 defer。(说明:文中的片段代码需结合上下文,放进完整程序中运行)
定义与调用
完整示例(存为 hello.go,用 go run hello.go 运行):
package main
import "fmt"
func sayHi() { fmt.Println("你好,Go!") } // 无参数、无返回值
func add(a, b int) int { return a + b } // 参数 a、b,返回 int
func main() {
sayHi()
fmt.Println(add(3, 5)) // 8
}
// 输出:
// 你好,Go!
// 8
定义格式:func 函数名(参数列表) 返回值类型 { 函数体 }。参数类型连续相同时可简写为 a, b int;Go 不支持函数重载。
多返回值与命名返回值
函数能一次返回多个值(最常用于 value, err := f());返回值还能先起名,最后用裸 return:
func div(a, b int) (int, int) { return a / b, a % b } // 返回商、余数
func rect(w, h int) (area, peri int) { // 命名返回值
area = w * h
peri = 2 * (w + h)
return // 裸返回 area、peri
}
// q, r := div(17, 5) → q=3, r=2;a, p := rect(4, 3) → a=12, p=14
可变参数
参数写成 nums ...int,就能接收任意个数(含 0 个)的参数,函数体内它就是一个切片:sum(1,2,3) 得 6,sum(1,2,3,4,5) 得 15。
func sum(nums ...int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
值传递与指针传递
默认按值传递:函数里改的是副本。要修改调用方的变量,就传指针(& 取地址,* 解引用):
func no(n int) { n = 100 } // 只改了副本,无效
func yes(p *int) { *p = 100 } // 通过指针修改原变量
// a := 1; no(a) → 1;yes(&a) → 100
slice、map、channel 是引用类型,直接传参就能修改内部元素,无需指针。指针的细节见《Go 指针》。
匿名函数与闭包
匿名函数没有名字,可赋值给变量,也能定义后立即执行。能捕获外层变量的匿名函数叫闭包:
double := func(x int) int { return x * 2 } // 匿名函数
fmt.Println(double(21)) // 42
next := func() func() int { // 闭包:记住外层变量 n
n := 0
return func() int {
n++
return n
}
}()
fmt.Println(next(), next()) // 1 2:函数返回后 n 依然存活
defer 延迟执行
defer 把调用推迟到当前函数返回前执行,常用于关闭文件、解锁等清理;多个 defer 按后进先出执行:
defer fmt.Println("先写的 defer")
defer fmt.Println("后写的 defer")
fmt.Println("主体") // 输出顺序:主体 → 后写的 defer → 先写的 defer
小结:多返回值、命名返回值、闭包与 defer 是 Go 函数最鲜明的特点,多写多练即可掌握。