- 面向对象就是使用方法来描述每个数据结构的属性和操作
-
在同一个结构体中,方法和字段来自同一个命名空间。所以不能同名。
-
可以将方法绑定到任何类型(数字,字符串,slice,map,函数)上,方便的为简单的类型定义附加的行为。
-
调用方法时,接收者也会被复制。如果接收者太大或者希望更新接收者,就应该定义指针接收者的方法。
-
真实的程序中,如果类型的任何一个方法使用指针接收者,那么所有的方法都应该使用指针接收者。
-
不允许本身是指针的类型进行方法声明。
-
如果方法定义中的接收者类型和实际调用方法的类型不符,编译器会做隐式转换
type T struct {} func (t *T)method() { /*...*/} v := T{} v.method() //合法,编译器隐式转换为 &t func (t T)method2() {/*...*/} pv := &T{} pv.method2() // 合法,编译器隐式插入 * 操作符
-
如果类型T的方法的接收者都是T(非*T),那么复制它的实例是安全的。如果有方法的接收者是指针,应该避免复制T的实例。
-
nil 是一个合法的接收者,在有把 nil 指针接收者方法中,应在方法内检查接收者是否是 nil,避免例如向值为 nil 的map 添加元素。
-
对于引用类型,例如map,在方法内对 map 变量数据结构的改变,例如键值对的改变,对方法调用者是可见的。但 map 变量自身是副本,对变量本身的改变,例如 m = nil, 对调用者是不可见的
- 如果结构体有内嵌成员,这个结构体可以直接调用内嵌成员的方法。编译器会生成额外的包装方法调用内嵌成员声明的方法。
-
方法也可以通过方法表达式转换为函数来使用。函数只需要提供实参而不需要提供接收者就能够调用。
-
方法表达式写为 T.f 或者(*T).f,可以赋值给方法变量
-
调用方法变量时需把接收者作为第一个形参
-
封装一个对象,必须使用结构体内非导出的字段。
-
封装提供三个好处
-
使用方不能直接修改对象的变量,所以不需要更多的语句检查变量的值
-
隐藏实现细节防止使用方依赖的属性发生改变
-
防止使用者肆意改变对象内的变量
-
-
Go中习惯省略方法中的Get,Fetch等冗余动词前缀