Go语言中所有的传参都是值传递(传值),都是一个副本,一个拷贝。且传参和赋值(=)的操作本质是一样的。
拷贝的内容分为 非引用类型 和 引用类型 两种类型
非引用类型:int、string、struct、array 这样就不能修改原内容数据。
引用类型:指针、map、slice、chan ,这样就可以修改原内容数据。
实例:
slice
package main
import (
"fmt"
)
func test(input []int) []int{
// input: 0x40c110->{address,4,4}
fmt.Printf("Slice inside address: %p\n",&input)
// input: 0x40c110->{address,4},但对address的修改影响到了val:0x40c0e0->{address,4}
input[0] = -1
input = append(input,5)
// input: 0x40c110->{address,5,8},但val仍然为0x40c0e0->{address,4}
fmt.Println(input,len(input),cap(input))
return input
}
func main() {
// val:0x40c0e0->{address,4}
val := []int{1,2,3,4}
fmt.Printf("Slice outside address: %p\n",&val)
fmt.Println(val,len(val),cap(val))
copyVal := test(val)
fmt.Printf("Slice outside address: %p\n",cap(val))
fmt.Printf("copySlice address: %p\n",©Val)
fmt.Println(copyVal,len(copyVal),cap(copyVal))
}
结果:
Slice outside address: 0x40c0e0
[1 2 3 4] 4 4
Slice inside address: 0x40c110
[-1 2 3 4 5] 5 8
Slice outside address: 0x40c0e0
[-1 2 3 4] 4 4
copySlice address: 0x40c100
[-1 2 3 4 5] 5 8
结论:
传入的是slice三元组的值拷贝,返回的slice三元组值拷贝给外部变量
map
map的原理跟slice类似
package main
import "fmt"
func ChangeMap(input map[int]string) {
input[2] = "changed"
input[3] = "itsname"
delete(input,1)
fmt.Printf("Inside input address: %p | %v\n",&input,input)
}
func main() {
tmpmap := make(map[int]string)
tmpmap[1] = "myname"
tmpmap[2] = "yourname"
fmt.Printf("Before change input address: %p | %v\n",&tmpmap,tmpmap)
ChangeMap(tmpmap)
fmt.Printf("After change input address: %p | %v\n",tmpmap)
}
结果:
Before change input address: 0x40e128 | map[2:yourname 1:myname]
Inside input address: 0x40e148 | map[2:changed 3:itsname]
After change input address: 0x40e128 | map[2:changed 3:itsname]
struct
struct跟slice和map不同,它是非引用类型
package main
import "fmt"
func main() {
p:=Person{"张三"}
fmt.Printf("Before change p address: %p | %v\n",&p,p)
modify(p)
fmt.Printf("After change p address: %p | %v\n",p)
}
type Person struct {
Name string
}
func modify(p Person) {
p.Name = "李四"
fmt.Printf("Inside change p address: %p | %v\n",p)
}
结果:
Before change p address: 0xc000010200 | {张三}
Inside change p address: 0xc000010220 | {李四}
After change p address: 0xc000010200 | {张三}
小编说
以上是编程之家为你收集整理的golang 函数 传入返回 slice/map/struct 本质全部内容。
如果觉得编程之家网站内容还不错,欢迎将编程之家推荐给好友。