第六章(方法)[下]
- 方法和函数一样,可以直接调用,还可以赋值给变量,或作为参数传递。依照具体引用方式的不同,可分为expression和value两种状态
method expression(方法表达式)
- 通过类型引用的 method expression 会被还原为普通函数样式,receiver是第一参数,调用时须显式传参。至于类型,可以是T或*T,只要目标方法存在于该类型方法集中即可
type N int
func (n N) test() {
fmt.Printf("test.n: %p, %d\n", &n, n)
}
func main() {
var n N = 25
fmt.Printf("test.n: %p, %d\n", &n, n) //test.n: 0xc000018058, 25
f1 := N.test //使用类型调用方法名赋值给f1
f1(n)//test.n: 0xc000018078, 25
f2 := (*N).test //虽然使用*N调用test方法,但是编译器会字段转换成普通类型N
f2(&n)//test.n: 0xc000018090, 25 >> 尽管*N方法集包装的test方法receiver类型不同,但编译器会按原定义类型拷贝传值
}
尽管*N方法集包装的test方法receiver类型不同,但编译器会保证按原定义类型拷贝传值
- 可以直接以表达式方式调用
var n N = 25
N.test(n) //test.n: 0xc0000180c0, 25
(*N).test(&n) //test.n: 0xc0000180e0, 25 >> 注意由于操作符优先级问题,*N必须加括号(*N)
method value (方法值)
// 方法值调用
package main
import "fmt"
type Student struct {
id int
name string
}
// 指针方法
func (s *Student) PointerMethod() {
fmt.Printf("我是指针方法:%p,%v\n", s, s)
}
// 值方法
func (s Student) ValueMethod() {
fmt.Printf("我是值方法:%p,%v\n", &s, s)
}
func main() {
// 方法值
stu := Student{1, "小明"}
pointerMethod := stu.PointerMethod
valueMethod := stu.ValueMethod
//1
valueMethod() //我是值方法:0xc000004090,{1 小明}
//2
pointerMethod() //我是指针方法:0xc000004078,&{1 小明}
stu.id = 2
stu.name = "小红"
//3
valueMethod() //我是值方法:0xc0000040d8,{1 小明}
//4
pointerMethod() //我是指针方法:0xc000004078,&{2 小红}
}