结构体
(1)结构指针接收者,顾名思义,会在方法内部改变该结构内部变量的值;
(2)结构值接收者,在方法内部对变量的改变不会影响该结构。
package main
import "fmt"
type My struct {
num int
}
func (m My) AddOne() {
m.num++
}
func (m *My) AddTwo() {
m.num += 2
}
func Test() {
my1 := My{1} //值接收者
my1.AddOne()
// 1 不改变num的值
fmt.Println(my1.num)
my2 := &My{1} // 指针接收者
my2.AddTwo()
// 3改变num的值
fmt.Println(my2.num)
}
func main() {
Test()
}
另外:
(3)对于指针接收者,如果你调用的是值方法,即使你是指针调用者,也不会改变你的结构内的变量值
(4)对于值接收者,如果你调用的是指针方法,即使你是值调用者,也会改变你的结构内的变量值
func Test1() {
my3 := My{1} // 值接收者
my3.AddTwo()
// 3 改变num的值
fmt.Println(my3.num)
my4 := &My{1} // 指针接收者
my4.AddOne()
// 1 不改变num的值
fmt.Println(my4.num)
}
接口
package main
import "fmt"
type Valueer interface {
printf()
}
type Value1 struct {
num int
}
type Value2 struct {
num int
}
func (self *Value1) printf() {
fmt.Println(self.num)
}
func (self *Value2) printf() {
fmt.Println(self.num)
}
func testValue() {
var te1 Valueer
te1 = Value1{1}
te1.printf()
var te2 Valueer
te2 = Value2{1}
te2.printf()
}
func main() {
testValue()
}
上述代码编译出错:
说明一个结构实现了接口的指针接收方法的话,将该结构的值赋值给接口是不行的,他不能找到该方法。
具体的语言规范里定义的规则如下:
类型 *T 赋值给interface的可调用方法集包含接受者为 *T 或 T 的所有方法集
这条规则说的是如果我们用来调用特定接口方法的接口变量是一个指针类型,那么方法的接受者可以是值类型也可以是指针类型.
类型 T 赋值给interface的可调用方法集包含接受者为 T 的所有方法
由以上两条规则,知道我们不符合这两条规则。
更改如下:
func testValue() {
var te1 Valueer
te1 = &Value1{1}
te1.printf()
var te2 Valueer
te2 = &Value2{1}
te2.printf()
}