2020.07.28
1041
Go 中函数传参仅有【值】传递一种方式,【值】传递一种方式,【值】传递一种方式(重要事说三遍)。
在Golang 中函数传参仅有值传递一种方式,但是跟c++或者PHP的不同,并没有引用传值,没有将实际参数的地址传递到函数中。
例如:
i :=3
i1 := &i
此时i1是指针变量,它有自已内存地址,存储的值为 指针类型 *int=xxxxx xxx为i变的内存地址,使用 c :=*i1 可以返回i1指向变量的值, 使用 *i1 =5 可修改i1指向变量的值。
另外i1指针变量本身的地址可以使用 &来获取 &i1。
有如下函数:
func c() (i int) {
i = 3
i1 := &i //&操作符(前缀)来获取变量的内存地址(取地址操作)
//变量 i 的地址使用变量 i1 进行接收,i1的类型为*T,称做 T 的指针类型,*代表指针。
fmt.Printf("i变量本身地址为:%p\n", &i) //0xc00000c2e0
fmt.Printf("i1指针变量本身地址为:%p\n", &i1) //0xc000006028
fmt.Printf("i1指针变量存值为:%s\n", i1) //*int=0xc00000c2e0
fmt.Printf("i1指针变量指向存值为:%s\n", *i1) //3
defer func(i2 *int) {
fmt.Printf("i2指针变量本身地址为:%p\n", &i2) //0xc000006038
fmt.Printf("i2指针变量指向存值为:%s\n", *i2) //:3
fmt.Printf("i2指针变量存值为:%s\n", i2) //*int=0xc00000c2e0
*i2 = 5 //*操作符的根本意义就是操作指针指向的变量
}(i1)
return
}
实参i1 与 形参i2 的地址各自互不相关,说明在参数传递中发生了值拷贝,但他们指向了变量i的地址...所以可以修改i值,在函数 defer 中,形参 i2 的地址与实参 i1 的地址并不一样,但是他们在内存中的值都是变量 i 的地址,因此可以通过指针相关的操作来改变i的值。
那么指针变量pa传给函数的形参p后,形参将会是它在栈上的一份拷贝,他们本身将各自拥有不同的地址,但是二者的值是一样的(都是变量a的地址)。
最后要说的是, 引用类型和传引用是两个概念。在Golang中 slice、map、channel都是引用类型。通过传递给函数时,是可以被修改的。
如下:
map[aa:11 bb:22]
map[aa:ccc bb:22]
func change(qqs map[string]string) {
qqs["aa"] = "ccc"
}
qq := make(map[string]string)
qq["aa"] = "11"
qq["bb"] = "22"
fmt.Print(qq)
change(qq)
fmt.Print(qq)
上程序会输出:
2018.09.25
6728
新机型一发布,设计师们就要考虑适配问题。关于适配的文章看了几篇了? 眼花缭乱否? 不如看一篇简单直接的!