6.方法
方法是与对象实例(instance)绑定的特殊函数
方法面对对象编程,维护和展示对象自身状态。
函数专注与算法流程,接受参数并且完成逻辑运算,返回结果并清理现场
接收参数可以是指针类型,调用时决定是否复制
note:不能为指针和接口定义方法,即类型N不能是接口或者指针
编译器可以根据接收参数类型,自动在值与指针间转换
type N int func (n N) copy() { fmt.Printf("%p, %v\n", &n, n) } func (n *N) ref() { fmt.Printf("%p, %v\n", n, *n) } // ----------------------------- func main() { var a N = 25 fmt.Printf("%p\n", &a) // 0xc000014080 a.copy() // 0xc000014088, 25 N.copy(a) // 0xc0000140a0, 25 a++ a.ref() // 0xc000014080, 26 (*N).ref(&a) // 0xc000014080, 26 }
type N int func (n N) copy() {} func (n *N) ref() {} //--------------------- func main() { var a N = 25 var p *N = &a a.copy() a.ref() // (*N).ref(&a) p.copy() // N.copy(*p) p.ref() }
不能以多级指针调用方法
6.1匿名嵌入
同名遮蔽,结构体中有相同的字段名,按最小优先原则访问。
若两个同名方法深度相同,则需要显式指出
6.2方法集
根据接收参数(receiver)的不同,可分为 T 和 T 两种视角。
T.set = T
T.set = T + *T
原因是 接口会复制对象,而复制品不能寻址
而×T实现接口,取值和复制指针都没问题
6.3方法值
方法除了直接调用外,还可以赋值给变量,或者作为参数传递
type N int func (n N) copy() { fmt.Printf("%p, %v\n", &n, n) } func (n *N) ref() { fmt.Printf("%p, %v\n", n, *n) } // ----------------------------- func main() { var n N = 100 // expression var e func(*N)() = (*N).ref e(&n) // value var v func() = n.ref v() }
将copy还原为了普通函数