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 函数最鲜明的特点,多写多练即可掌握。

笔记加载中…