一、引言
在定义结构体方法时,既可以让结构体类型本身实现方法,也可以让结构体指针类型实现方法,这两种实现方式有什么区别成为开发过程中的部分开发同学的问题,这里就以本人所了解的内容做个说明,希望对各位读者有一定帮助,如内容有误欢迎指正
二、代码示例说明
下方代码首先定义了一个接口Run
,Run
接口仅有一个Do()
方法,然后分别定义 Dog
和Cat
两个类型,Dog
类型本身实现Run
接口,Cat
则是其指针类型实现Run
接口,通过main
方法的调用以及代码注释即可理解两者的区别。
package main
import "fmt"
// Run run action interface
type Run interface {
Do()
}
// Dog dog struct
type Dog struct {
Name string
}
// 1. (d Dog) 可以看做是 Do 方法的一个特殊的参数,类似 python 的 self 一样,在 Dog 类型的实例在调用 Do 方法时把自身传递给了 Do 方法
// 由于这里是值传递,所以方法中对 Name 字段的赋值不会改变原始实例
// 2. Dog 实现了 Run,同时代表 *Dog 也实现了 Run
func (d Dog) Do() {
d.Name = "dog"
fmt.Println("dog struct do")
}
// Cat cat struct
type Cat struct {
Name string
}
// 1. (c *Cat) 可以看做是 Do 方法的一个特殊的参数,类似 python 的 self 一样,在 *Cat 类型的实例在调用 Do 方法时把自身传递给了 Do 方法
// 由于这里是指针传递,所以方法中对 Name 字段的赋值会改变原始实例 Name 字段的值
// 2. *Cat 实现 Run 不能代表 Cat 实现 Run
func (c *Cat) Do() {
c.Name = "cat"
fmt.Println("cat point do")
}
// public function
func DoRun(r Run) {
r.Do()
}
func main() {
DoRun(Dog{})
DoRun(&Dog{}) // Dog 实现了 Run,同时代表 *Dog 也实现了 Run,所以可以传递指针
DoRun(&Cat{})
// DoRun(Cat{}) // *Cat 实现 Run 不能代表 Cat 实现 Run,所以这样的调用会报错
}
三、总结
在 Go 语言中,如果结构体实现了方法则结构体指针类型也实现了该方法,但如果结构体指针实现了该方法,结构体本身并没有实现该方法,这是一个不对称的特性