package main
type My struct {
num int
}
func (self My) AddOne() {
self.num++
}
func (self *My) AddTwo() {
self.num += 2
}
// (1)结构指针接收者,顾名思义,会在方法内部改变该结构内部变量的值;
// (2)结构值接收者,在方法内部对变量的改变不会影响该结构。
func Test() {
my1 := My{1} // 值接收者调用值方法
my1.AddOne() // 形参和实参一致
fmt.Println(my1.num)// 不改变num的值
my2 := &My{1} // 指针接收者调用指针方法
my2.AddTwo() // 形参和实参一致
fmt.Println(my2.num)// 改变num的值
}
// (3)对于结构指针接收者,如果你调用的是值方法,即使你是指针调用者,也不会改变你的结构内的变量值
// (4)对于值接收者,如果你调用的是指针方法,即使你是值调用者,也会改变你的结构内的变量值
func Test2() {
my3 := My{1}// 值接收者调用指针方法 形参和实参不一致
my3.AddTwo()// 实际上编译器会对my3进行隐式的转换 将my3转化成&my3指针类型
fmt.Println(my3.num) // 3 改变num的值
my4 := &My{1} // 指针接收者调用值方法 形参和实参不一致
my4.AddOne() // 实际上 编译器会从my4指针类型中 解引用出my4实际的取值
fmt.Println(my4.num)// 1 不改变num的值
}
// 不允许本身是指针类型的进行方法声明
总结: 只有三种情况满足方法表达式
1.实参和形参的类型一致 即都是T类型或者都是*T类型
2.实参是T类型 而形参数*T类型 编译器会隐式的将T转化成*T
3.实参是*T类型 而形参是T类型 编译器会隐式的解引用实参(接受者) 获得实际的取值。