**下面这个要铭记**
值变量存储
变量地址-> 数据
指针变量储存
变量地址-> 地址-> 数据
因为goland语法糖的存在,所有我们在使用指针类型时感觉跟值类型没什么区别,其实是go自动帮我们添加了"*" ;
在golang中无论是值方法还是指针方法,在方法或者函数中其实都是值拷贝,只不过指针类型的拷贝的是一个地址(函数中的参数也是值拷贝)
总结
1.变量为指针类型可以使用值方法,也可以使用指针方法;
2.变量为值类型只可以使用值方法,也可以使用指针方法(在继承中不属于实现);
type SS struct {
Age *int
DD int
}
type AA interface {
DDD()
}
func main() {
sPtr := &SS{
new(int),
0,
}
sValue := SS{
new(int),
0,
}
test(sPtr)
test(sValue) // 无法将 'sValue' (类型 SS) 用作类型 AA 类型未实现 'AA',因为 'DDD' 方法有指针接收
}
func (p *SS) DDD() {
p.DD = 10
}
func test(aa AA) {
aa.DDD()
}
我们根据成员类型(field),数据类型(var),方法类型(function),分为三类讨论
1.当结构体的成员为值类型时
(1)数据类型为值类型
<1> 方法为值类型:
这种就是正常的方法,对成员赋值不会影响原值
type SS struct {
Age *int
DD int
}
func main() {
s := SS{
new(int),
0,
}
fmt.Println(*s.Age, s.DD) // 0 0
s.Name()
s.DDD()
fmt.Println(*s.Age, s.DD) // 100 0
}
func (p SS) Name() {
*p.Age = 100
}
func (p SS) DDD() {
p.DD = 10
}
<2> 方法为指针类型:
会影响原值
type SS struct {
Age *int
DD int
}
func main() {
s := SS{
new(int),
0,
}
fmt.Println(*s.Age, s.DD) // 0 0
s.Name()
s.DDD()
fmt.Println(*s.Age, s.DD) // 100 10
}
func (p SS) Name() {
*p.Age = 100
}
func (p *SS) DDD() {
p.DD = 10
}
(2)数据类型为指针类型时
<1> 方法为值类型:
不会影响原值(这里可能会疑惑了,其实这里有语法糖,发现是指针类型的数据,自动帮我们加*了,真坑爹啊)
type SS struct {
Age *int
DD int
}
func main() {
s := &SS{
new(int),
0,
}
fmt.Println(*s.Age, s.DD) // 0 0
s.Name()
s.DDD()
fmt.Println(*s.Age, s.DD) // 100 0
}
func (p SS) Name() {
*p.Age = 100
}
func (p SS) DDD() {
p.DD = 10
}
<2> 方法为指针类型时
会影响原值
type SS struct {
Age *int
DD int
}
func main() {
s := &SS{
new(int),
0,
}
fmt.Println(*s.Age, s.DD) // 0 0
s.Name()
s.DDD()
fmt.Println(*s.Age, s.DD) // 100 10
}
func (p SS) Name() {
*p.Age = 100
}
func (p *SS) DDD() {
p.DD = 10
}
2.当结构体的成员为指针类型时(代码见上age的打印)
(1)数据类型为值类型
<1> 方法为值类型:
会影响原值
<2> 方法为指针类型:
会影响原值
(2)数据类型为指针类型时
<1> 方法为值类型:
会影响原值
<2> 方法为指针类型时
会影响原值