1. 问题
晚上看到很多方法里面传递了对象还传递了指针对象,但是感觉之前学习的时候,传递指针对象和传递对象没有什么区别(取值上面),就开始了这个问题。
问题就是两者都是传递,都可以取到正确的值,但是为什么要分开传递呢?
2. 结论
结论的话:
- 如果传递参数仅仅是对象的话,则此对象无论进行什么操作,都是在原对象的拷贝对象上做的,并不会影响传递的对象,除非将处理后的对象返回替代原对象,则修改会生效。
- 如果传递参数是指针对象的话,则对象进行的所有的修改操作都是建立在直接修改原对象的基础之上的,因为传递的本身就是原对象的地址。
3. 验证
func main() {
stu := Student{
"Cao Duanxi", 10, "南京",
}
fmt.Println("传递之前:", stu.name)
fmt.Println("传递之前的地址:",&stu.name)
tt(stu)
fmt.Println("传递对象之后:", stu.name)
tt2(&stu)
fmt.Println("传递指针对象之后:", stu.name)
}
/**
指针与非指针传递的区别在于:
如果是指针变量传递,所有的传递修改都是直接修改的地址
而如果是对象的话,传递的则是一份拷贝的对象而已,并不是真实的对象
*/
func tt(stu Student) {
fmt.Println("传递对象的地址:",&stu.name)
stu.name = "caoduanxi"
}
func tt2(stu *Student) {
fmt.Println("传递指针对象的地址:", &stu.name)
stu.name="caoduanxi"
}
type Student struct {
name string
age int
address string
}
具体的输出如下:
传递之前: Cao Duanxi
传递之前的地址: 0xc000074330
传递对象的地址: 0xc000074360
传递对象之后: Cao Duanxi
传递指针对象的地址: 0xc000074330
传递指针对象之后: caoduanxi
从结果中可以看到传递对象,而tt()
方法并没有返回值,故并没有改变实际的参数值,而且对于传递对象来说可以看到stu.name
的地址与原对象地址不一致,则表明为拷贝的一份对象。
而传递指针的tt2()
方法也没有返回值,但是因为传递的是指针,即原对象的地址,在输出中可以看到,其参数stu.name
的地址与原对象地址是一致的,而且后续参数值的修改输出也验证了,tt2()
方法可以直接修改原对象。
tips:上面程序中并没有取结构体的地址,这是因为结构体是指就类似于数组一样,内部的属性各有各的地址,结构体的地址无法取到。
3. 小结
从上面的结论和验证可以看出,传递对象和传递指针对象差异在于传递副本还是传递原对象地址。
Keep thinking, keep coding! 2020年12月17日22:37:14 写于南京 加油!