V
Vel·ToolKit
简洁 · 高效 · 即开即用
ZH
第 11 章 / 共 20 章

方法

值接收者 vs 指针接收者

为类型定义方法

方法本质是带接收者的函数。接收者可以是任意当前包定义的命名类型。

package main

import "fmt"

type Rect struct{ W, H float64 }

func (r Rect) Area() float64 {
    return r.W * r.H
}

func main() {
    r := Rect{3, 4}
    fmt.Println(r.Area()) // 12
}

值接收者 vs 指针接收者

  • 值接收者:调用时复制接收者,方法内修改不影响调用者
  • 指针接收者:调用方法可以修改接收者;避免大结构体的复制开销
  • 一般规则:同一类型的方法尽量保持接收者形式一致;要修改状态或类型较大就用指针接收者
package main

import "fmt"

type Rect struct{ W, H float64 }

func (r *Rect) Scale(f float64) {
    r.W *= f
    r.H *= f
}

func main() {
    r := Rect{3, 4}
    r.Scale(2)     // Go 自动取地址
    fmt.Println(r) // {6 8}
}

方法值与方法表达式

方法可以像普通函数一样被引用:r.Area 是方法值(绑定接收者),Rect.Area 是方法表达式(接收者作首参)。

package main

import "fmt"

type Rect struct{ W, H float64 }

func (r Rect) Area() float64 { return r.W * r.H }

func main() {
    r := Rect{3, 4}

    fn := r.Area      // 方法值
    fmt.Println(fn()) // 12

    expr := Rect.Area  // 方法表达式
    fmt.Println(expr(r)) // 12
}