在写代码的过程中,经常会会涉及到方法的receiver类型选择的问题,通常会纠结于用T还是*T,记住以下原则问题便迎刃而解:
- 要修改实例状态,用*T。
- 无须修改状态的小对象或固定值,建议用T。
- 大对象建议用*T,以减少复制成本。
- 引用类型、字符串、字典、函数等指针包装对象,直接用T。
- 若包含Mutex等同步字段,用*T,避免因赋值造成锁操作无效。
- 其他无法确定的情况都用*T。
可使用实例值或指针来调用方法,编译器会根据方法receiver类型自动在基础类型和指针类型间转换。
type N int
func (n N)Value(){
n++
fmt.Printf("%p, %v\n",&n,n)
}
func (n *N)Pointer(){
*n++
fmt.Printf("%p, %v\n",n,*n)
}
func main() {
var a N = 25
p:=&a
a.Value()
a.Pointer()
p.Value()
p.Pointer()
fmt.Printf("%p, %v\n",&a,a)
}
另外例如字典等本身就是指针包装对象的,取地址时没必要再加&地址符。
有疑问加站长微信联系(非本文作者)