这是我参与更文挑战的第10天,活动详情查看: 更文挑战
本节主要学习,函数或者方法在传递参数的过程中,遇到值类型,指针类型时会发生什么情况,并从demo入手深入了解其原理。
从Demo入手,运行以下demo更深刻的了解其内部的原理
type person struct {
name string
age int
}
//
func updatePerson(p person) {
p.name = "jasen"
p.age = 20
}
func main() {
p := person{"南吕", 18}
updatePerson(p) // updatePerson(&p)
fmt.Println("After Update")
fmt.Println("name:", p.name, "age:%d", p.age)
}
// 将updatePerson函数的参数改成指针参数时,
func updatePerson(p *person){
p.name = "jasen"
p.age = 20
}
复制代码
运行结果:
调用updatePerson后,重新输出时,name和age都不变。
但是,如果将函数的参数改成指针参数时,重新运行输出的结果就是变化了
上述的demo,就是值类型参数和指针类型参数的区别
变量都存储在内存中,每个内存都有一个内存地址,如果想要修改内存中的数据,需要找到这个内存地址。
值类型
函数传递的参数是值类型。
type person struct {
name string
age int
}
func updatePerson(p person) {
fmt.Printf("update函数内:p的地址:%p\n",&p)
p.name = "jasen"
p.age = 20
}
func main() {
p := person{"南吕", 18}
fmt.Printf("main函数内:p的地址:%p\n",&p)
updatePerson(p)
fmt.Println("After Update==> name:", p.name, "age:", p.age)
}
复制代码
现象:p的内存地址不一致,说明main函数中的变量p和updatePerson函数的变量p不是同一个。
原因:函数传参是值传递,值传递指的是传递原来的数据的复制品,不是数据本身。他们的内存地址是不一致的,但是内存中存储的数据是一样的
值类型:struct结构体,浮点型,整型,字符串,布尔类型,数组
指针类型
指针类型的变量是实际是内存地址,所以如果在函数参数传递是指针类型的话,则相当于传递内存地址,那将传递的是同一个变量。
修改上述demo,从传参为指针类型的demo来观察结果:
type person struct {
name string
age int
}
func updatePerson(p *person) {
fmt.Printf("update函数内:p的地址:%p\n",p)
p.name = "jasen"
p.age = 20
}
func main() {
p := person{"南吕", 18}
fmt.Printf("main函数内:p的地址:%p\n",&p)
updatePerson(&p)
fmt.Println("After Update==> name:", p.name, "age:", p.age)
}
复制代码
现象:内存地址是同一个,则p对应的数据也是同一份数据
原因:传递指针类型,即内存地址,通过内存地址可找到原数据的那块内存,那么修改它就等于修改了原数据
指针类型:加*都是表示指针类型
引用类型
严格来说,Go语言中没有引用类型。为便于理解,将其称为引用类型。
只要通过关键字make声明的变量都可称为应用类型。比如map、chan、slice切片、接口、函数。
上述demo我们将其换成map,并打印其内存地址。
func main(){
stuMap := make(map[string]int)
stuMap["nanlv"] = 18
fmt.Printf("main函数内:stuMap的地址:%p\n",stuMap)
updateMap(stuMap)
fmt.Println("nanlv的年龄为",stuMap["nanlv"])
}
func updateMap(stuMap map[string]int){
fmt.Printf("updateMap函数内:stuMap的地址:%p\n",stuMap)
stuMap["nanlv"] = 30
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END