NIUCLOUD是一款SaaS管理后台框架多应用插件+云编译。上千名开发者、服务商正在积极拥抱开发者生态。欢迎开发者们免费入驻。一起助力发展! 广告
## 指针对象 **什么时候使用指针对象呢?当receiver较大的时候,或者需要修改receiver中的字段值的时候**,拷贝值是很耗费性能的.所以此时应该使用指针对象. ~~~ func (p *Point) ScaleBy(factor float64) { p.X *= factor p.Y *= factor } ~~~ 1. 不管你的method的receiver是指针类型还是非指针类型,都是可以通过指针/非指针类型进行调用的,编译器会帮你做类型转换。 2. 在声明一个method的receiver该是指针还是非指针类型时,你需要考虑两方面的内部,第一方面是这个对象本身是不是特别大,如果声明为非指针变量时,调用会产生一次拷贝;第二方面是如果你用指针类型作为receiver,那么你一定要注意,这种指针类型指向的始终是一块内存地址,就算你对其进行了拷贝。 ## 例子 值方法: ~~~ type User struct { Name string } func (u User) PrintName() { //注意User是值类型 fmt.Println(u.Name) } func main() { u1 := &User{"jack"} //但是并不影响我们使用"&"取地址去调用它,golang的编译器会帮我们进行解引用加"*"去调用 u1.PrintName() User{"jack"}.PrintName() //这里也可以直接调用receiver是值类型的方法. } ~~~ 指针方法: ~~~ type User struct { Name string } func (u *User) PrintName() { //注意是指针方法 fmt.Println(u.Name) } func main() { u1 := User{"jack"} //编译器会自动帮我们加上"&" u1.PrintName() //调用成功 User{"jack"}.PrintName() //报错,因为只有"变量"是有地址的,golang编译器才能帮我们去找到"变量"的地址,而直接调用是无法找到这个地址的,所以会报错. } ~~~ ## 约定 当方法的receiver的类型必须保持一致,如果是指针就全都是指针,哪怕是用不到. ## 歧义 为了避免歧义,类型是指针的是不允许有方法的.因为这样不知道调用的receiver到底是什么了.