Open 499689317 opened 4 years ago
如果实现了接收者是值类型的方法,会隐含地也实现了接收者是指针类型的方法。
package main
import "fmt"
type coder interface { code() debug() }
type Gopher struct { language string }
func (p Gopher) code() { fmt.Printf("I am coding %s language\n", p.language) }
func (p *Gopher) debug() { fmt.Printf("I am debuging %s language\n", p.language) }
1. 方式一
// 正常打印 func main() { var c coder = &Gopher{"Go"} c.code() c.debug() }
2. 方式二
// 报错 func main() { var c coder = Gopher{"Go"} c.code() c.debug() }
* 两者分别使用场景 ____ 如果方法的接收者是值类型,无论调用者是对象还是对象指针,修改的都是对象的副本,不影响调用者;如果方法的接收者是指针类型,则调用者修改的是指针指向的对象本身。 使用指针作为方法的接收者的理由: 方法能够修改接收者指向的值。 避免在每次调用方法时复制该值,在值的类型为大型结构体时,这样做会更加高效。 是使用值接收者还是指针接收者,不是由该方法是否修改了调用者(也就是接收者)来决定,而是应该基于该类型的本质。 如果类型具备“原始的本质”,也就是说它的成员都是由 Go 语言里内置的原始类型,如字符串,整型值等,那就定义值接收者类型的方法。像内置的引用类型,如 slice,map,interface,channel,这些类型比较特殊,声明他们的时候,实际上是创建了一个 header, 对于他们也是直接定义值接收者类型的方法。这样,调用函数时,是直接 copy 了这些类型的 header,而 header 本身就是为复制设计的。 如果类型具备非原始的本质,不能被安全地复制,这种类型总是应该被共享,那就定义指针接收者的方法。比如 go 源码里的文件结构体(struct File)就不应该被复制,应该只有一份实体 ____ ### 接口interface * 因为空接口没有定义任何函数,所以Go中任何类型都实现了空接口
Go Struct方法定义中指针接收与值接收
如果实现了接收者是值类型的方法,会隐含地也实现了接收者是指针类型的方法。
import "fmt"
type coder interface { code() debug() }
type Gopher struct { language string }
func (p Gopher) code() { fmt.Printf("I am coding %s language\n", p.language) }
func (p *Gopher) debug() { fmt.Printf("I am debuging %s language\n", p.language) }
// 正常打印 func main() { var c coder = &Gopher{"Go"} c.code() c.debug() }
// 报错 func main() { var c coder = Gopher{"Go"} c.code() c.debug() }