go笔记-值传递、引用传递
在函数调用时,需要注意是值传递/引用传递
注意:golang内没有引用传递
1. 对于slice
eg:
func sliceModify(slice []int) {
// slice[0] = 88
slice = append(slice, 6)
}
func main() {
slice := []int{1, 2, 3, 4, 5}
sliceModify(slice)
fmt.Println(slice)
}
out: [1 2 3 4 5]
虽然说数组切片在函数传递时是按照引用的语义传递的,比如说在 sliceModify 函数里面 slice[0] = 88,在方法调用的上下文中,调用函数对slice引用的改表是看得见的。
但是在对slice进行append操作的时候,返回的是新的引用,并非原始引用。
解决:
传递指针的指针
eg:
func sliceModify(slice *[]int) {
*slice = append(*slice, 6)
}
func main() {
slice := []int{1, 2, 3, 4, 5}
sliceModify(&slice)
fmt.Println(slice)
}
out: [1 2 3 4 5 6]
2. 对于map
通过src/runtime/hashmap.go
源码可见,make函数返回的是一个hmap类型的指针hmap。也就是说map===hmap。
eg:
package main
import "fmt"
func main() {
dataMap := make(map[string]int)
dataMap["name1"] = 1
mp := &dataMap
fmt.Printf("原始map的内存地址:%p\n", mp)
updateData(dataMap)
fmt.Println("map值更新为:", dataMap)
}
func updateData(data map[string]int) {
fmt.Printf("updateData内接收的map的内存地址:%p\n", &data)
data["name1"] = 2
}
输出:
原始map的内存地址:0xc0000b0018
updateData内接收的map的内存地址:0xc0000b0028
map值更新为: map[name1:2]
3. 对于自己实现的struct
package main
import "fmt"
type Data struct {
Field1 string
}
func main() {
data := Data{
Field1: "1",
}
dp := &data
fmt.Printf("原始data的内存地址:%p\n", dp)
fmt.Printf("原始datad值:%v\n", data)
updateDataField(data)
fmt.Println("map值更新为:", data)
updateDataFieldUsePointer(&data)
fmt.Println("map值更新为:", data)
}
func updateDataField(data Data) {
fmt.Printf("updateDataField内接收的map的内存地址:%p\n", &data)
data.Field1 = "2"
}
func updateDataFieldUsePointer(dp *Data) {
fmt.Printf("updateDataFieldUsePointer内接收的map的内存地址:%p\n", dp)
dp.Field1 = "2"
}
结果:
原始data的内存地址:0xc0000881e0
原始datad值:{1}
updateDataField内接收的map的内存地址:0xc000088200
map值更新为: {1}
updateDataFieldUsePointer内接收的map的内存地址:0xc0000881e0
map值更新为: {2}
可见自定义的Data
和map
类型不同,
自定义的struct在作为函数参数时,是值传递
其内部字段未被修改。如果想修改则需要使用对应的指针。