Skip to main content

函数与方法

多返回值、方法接收者,以及值/指针接收者的直觉。

函数声明

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

// 同类型参数可合并
func add2(a, b int) int {
return a + b
}

可变参数:

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

sum(1, 2, 3)
sum([]int{1, 2}...) // 展开 slice

函数也是值,可赋给变量、作参数。

多返回值与命名返回

func div(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}

q, err := div(10, 2)
if err != nil {
// ...
}

命名返回值:在签名里起名,可用裸 return

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

入门阶段:错误用 (T, error);命名返回适可而止,避免影响可读性。错误处理细节见进阶「错误处理」。

方法:接收者

方法是带接收者的函数:

type Counter struct {
n int
}

func (c Counter) Value() int { // 值接收者
return c.n
}

func (c *Counter) Inc() { // 指针接收者
c.n++
}

var c Counter
c.Inc()
fmt.Println(c.Value()) // 1

调用时 Go 会自动取址/解引用:c.Inc() 等价 (&c).Inc()

值接收者 vs 指针接收者

选择典型动机
值接收者小对象、只读、不想暴露可变性
指针接收者要改接收者;大结构体避免拷贝;与接口方法集一致

约定:同一类型的方法接收者尽量统一(都用指针或都用值),减少心智负担。

type Buf struct {
data []byte
}

func (b *Buf) Append(p []byte) {
b.data = append(b.data, p...)
}

若类型需要实现某接口且接口方法是指针接收者,则只有 *T 实现该接口(进阶「接口与组合」)。

小结

  1. 多返回值是惯用错误通道:(result, error)
  2. 方法 = 函数 + 接收者
  3. 要改状态 / 大对象 → 指针接收者
  4. 同一类型接收者风格保持一致

上一篇:控制流 · 下一篇:包与模块初识