为什么在函数传参时,数组参数有无固定长度,会产生这样的差距,就是arr5里面的内容不会被改变,arr7却会改变,刚开始学go,求大佬赐教

codeYuanY · 2020-10-07 20:27:50 · 971 次点击

楼上讲的不够准确,容易陷入坑里面。Slice并不是地址传递,而是一个引用类型

  1. 在Golang里面,所有函数的参数都是值传递,传递过程会将变量进行值拷贝
  2. Slice是引用类型,本质并不是一个单独的类型,而是由三个部分组成,如下所示
    type _slice struct {
     elements unsafe.Pointer // 引用着底层存储在间接部分上的元素
     len      int            // 长度
     cap      int            // 容量
    }
    
  3. 其中elements底层数组的指针,同时也是Slice称之为引用类型的根本
  4. 当函数内部发生扩容,导致底层数组改变,就不会影响外部作用域的底层数组,谨记这一点
#3
更多评论

这是一个关于array与slice的问题

这两个看起来长得差不多,刚开始的确挺容易弄混淆的

package main

import (
    "fmt"
)

// 数组array-值传递
func Modify1(array [5]int) [5]int {
    array[0] = 300
    return array
}

// slice-地址传递
func Modify2(array []int) []int {
    array[0] = 300
    return array
}

func main() {
    // 数组-需要明确指定大小
    arr5 := [5]int{1, 2, 3, 4, 5}
    arr6 := Modify1(arr5)
    fmt.Println("arr5:", arr5) // 打印结果:[1 2 3 4 5]
    fmt.Println("arr6:", arr6) // 打印结果:[300 2 3 4 5]

    // slice-不需要明确指定大小
    arr7 := []int{1, 2, 3, 4, 5}
    arr8 := Modify2(arr7)
    fmt.Println("arr7:", arr7) // 打印结果:[300 2 3 4 5]
    fmt.Println("arr8:", arr8) // 打印结果:[300 2 3 4 5]

    /*
        // 数组-大小不可以变化
        // 此处报错: ./main.go:32:16: first argument to append must be slice; have [5]int
        arr9 := append(arr5, 6)
        fmt.Println("arr9:", arr9) // 此处报错
    */

    // slice-大小可以变化
    arr10 := append(arr7, 6)
    fmt.Println("arr10:", arr10) // 打印结果:[300 2 3 4 5 6]
}

<br/>

明确指定大小即固定长度的为array <br/> 动态改变大小即不固定长度的为slice <br/> 在函数传递中,array是值传递,slice是地址传递 <br/>

<br/> 明确这个就应该很容易理解啦 <br/> arr5 是 array --- 值传递 --- 不改变<br/> arr7 是 slice --- 地址传递 --- 改变<br/> <br/>

传递一个小技巧

在写代码的三个点后面加上golang,代码可以变得高亮

#1

上面预览的格式有点错乱,重新发布一下总结

明确指定大小即固定长度的为array 
动态改变大小即不固定长度的为slice
在函数传递中,array是值传递,slice是地址传递

明确这个就应该很容易理解啦
arr5 是 array --- 值传递 --- 不改变
arr7 是 slice --- 地址传递 --- 改变

传递一个小技巧

在写代码的三个点后面加上golang,代码可以变得高亮

#2