第六章(方法)[下]

  • 方法和函数一样,可以直接调用,还可以赋值给变量,或作为参数传递。依照具体引用方式的不同,可分为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 小红}

}

posted @ 2023-01-14 00:16  巴达克  阅读(12)  评论(0编辑  收藏  举报