go语言参数传递

2020-11-09  本文已影响0人  明明就_c565

原理

Go语言中所有的传参都是值传递(传值),都是一个副本,一个拷贝。因为拷贝的内容有时候是非引用类型(int、string、struct等这些),这样就在函数中就无法修改原内容数据;有的是引用类型(指针、map、slice、chan等这些),这样就可以修改原内容数据。

一个例子

func change(a []int) {

    fmt.Printf("v=%v,p=%p\n", a, &a)

    a = append(a, 3)

    fmt.Printf("v=%v,p=%p\n", a, &a)

    a = append(a, 4)

    a[0] = 11

    a[1] = 22

    fmt.Printf("v=%v,p=%p\n", a, &a)

}

func test5() {

    a1 := make([]int, 2, 3)

    a1[0] = 1

    a1[1] = 2

    fmt.Printf("v=%v,p=%p\n", a1, &a1)

    change(a1)

    fmt.Printf("v=%v,p=%p\n", a1, &a1)

}

输出

说明

1,a和a1是两个slice 只不过slice中指针指向是一样的,a在追加时超过了cap,重新分配内存,a中的数据指针指向变化,但是并没有影响a1,只是在函数内a发生赋值而已,与函数外的a没有任何关系,若想改变a1,最好采用传递a1的指针。

2,append一定是从长度开始追加的。

3,函数传递的本质是值传递。

4,slice是一个包含len cap ptr的结构

5,无论数组还是切片,都有长度限制。也就是追加切片的时候,如果元素正好在切片的容量范围内,直接在尾部追加一个元素即可。如果超出了最大容量,再追加元素就需要针对底层的数组进行复制和扩容操作了。

上一篇下一篇

猜你喜欢

热点阅读