go语言 各数据类型传值函数改变是否影响原值

编程入门 行业动态 更新时间:2024-10-12 08:23:06

go语言  各<a href=https://www.elefans.com/category/jswz/34/1768302.html style=数据类型传值函数改变是否影响原值"/>

go语言 各数据类型传值函数改变是否影响原值

变量

func main() {v := 12fmt.Println("src:", v)change(v)fmt.Println("after change:", v)p := 12changep(&p)fmt.Println("after changep:", p)
}func change(v int) {v = 33
}func changep(p *int) {*p = 55
}/*
src: 12
after change: 12
after changep: 55
*/

可以看到:v的值依然是12,而p的值由12改变为55

  • 变量在传递函数时是值拷贝,会在内存中另开辟一个地方存放拷贝值,而形参就指向这个地址

  • 当你传递指针给函数时,形参和原变量同时指向改地址,所以改变地址中存放的值,则原变量的值当然会变化

  • 同理于任何实际的值,如数组元素,结构体元素

普通数组

func main() {arr := [3]int{13, 23, 543}fmt.Println("src:", arr)change(arr)fmt.Println("after change:", arr)changep(&arr)fmt.Println("after change p:", arr)
}func change(a [3]int) {a[2] = 34
}func changep(p *[3]int) {p[1] = 45
}/*
src: [13 23 543]
after change: [13 23 543]
after change p: [13 45 543]
*/

结果:543依然是543,23变成了45
- go中普通数组和变量在底层是差不多的

slice

func main() {arr := []int{13, 23, 543}fmt.Println("src:", arr)change(arr)fmt.Println("after change:", arr)
}func change(a []int) {a[2] = 34
}/*
src: [13 23 543]
after change: [13 23 34]
*/

依然是这个例子,但是543变成了34
- slice其实包含了三部分,指针、长度、容量
- 所以slice传递的其实本身就有指针特性,不存在&arr这种操作

func main() {arr := make([]int, 3)fmt.Printf("src:%v, p:%p, len:%d, cap:%d\n", arr, arr, len(arr), cap(arr))add(arr)fmt.Println(arr)// 容量10arr2 := make([]int, 3, 10)fmt.Printf("src:%v, p:%p, len:%d , cap:%d\n", arr2, arr2, len(arr2), cap(arr2))add(arr2)fmt.Println(arr2)fmt.Println(arr2[:4])
}func add(a []int) {a = append(a, 43)fmt.Printf("add: %p\n", a)
}/*
src:[0 0 0], p:0x115da140, len:3, cap:3
add: 0x115d8480
[0 0 0]
src:[0 0 0], p:0x115e02d0, len:3 , cap:10
add: 0x115e02d0
[0 0 0]
[0 0 0 43]
*/

结果: 使用append函数对原slice是没有影响的,但是有差别

  • slice上面说了有个容量,他是可变的,当你不定义容量时,默认是初始化时的长度就是容量。而当你新增元素超过容量上限时,会在内存中重新分配地址,容量为之前的2倍,用于存储新slice,返回新的物理地址

  • 首先我们要明白,所有不含&的都是传递拷贝值,slice是因为本身含指针,导致修改元素值影响原slice,但是如果修改形参本身,而不是slice中的元素,是不会对原slice产生影响的,如arr1其实新slice传递给了形参a,但是只是传递给了拷贝值,而并非原slice

  • 其实新值43都插入成功了,只不过arr1插入到了新分配的slice,但是新slice并没有返回回去,而arr2容量足够,则不用重新分配,我们取arr2的前四位可以看到43已经成功插入,因为arr2本身长度只有3位,所以他的值只取了前三位

map

func main() {m := map[int]string{1: "one", 2: "two", 3: "three"}fmt.Println(m)change(m)fmt.Println(m)add(m)fmt.Println(m)
}func change(a map[int]string) {a[1] = "four"
}func add(a map[int]string) {a[5] = "five"
}/*
map[2:two 3:three 1:one]
map[1:four 2:two 3:three]
map[1:four 2:two 3:three 5:five]
*/

结果: 1的值由one改为了four,新增了5:five
- map和slice差不多,修改值都会改变原值,都是可变长度,但是map没有容量概念,新增值和使用delete函数也能改变原值,这里就不都进行演示

struct

func main() {p := Person{Name: "dabai",Age:  3,}change(p)fmt.Println(p)changep(&p)fmt.Println(p)
}func change(p Person) {p.Age = 4
}func changep(p *Person) {p.Age = 5
}/*
{dabai 3}
{dabai 5}
*/

结果:传值不改变,传指针改变
- 结构体和变量体现的是一样的

更多推荐

go语言 各数据类型传值函数改变是否影响原值

本文发布于:2024-03-23 18:38:50,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1741483.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数据类型   函数   原值   语言

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!