go 数组与slice的区别

爱被打了一巴掌 2022-11-26 07:51 272阅读 0赞

总结:

  1. 数组定长,定义的时候就需要确定。切片长度不定,append时会自动扩容

  2. 相同大小数组可以赋值,会拷贝全部内容。slice赋值和指针一样。数组和slice之间不能相互赋值。当然slice有自己的copy函数

  3. 数组也可以进行切片,返回值是一个slice,改变slice时会同步修改数组内容,相当于取得了这个数组的指针

测试:

  1. 数组定长,定义的时候就需要确定。切片长度不定,append时会自动扩容

    // 数组定义方式
    // 1 写明长度
    c1 := [5]int{1, 2, 3}
    // 2 自动获取长度
    c2 := […]int{1, 2, 3}

    // slice定义方式
    // 1 不写明长度就是slice
    c5 := []int{1, 2, 3}
    // 2 使用make定义的也是slice
    c6 := make([]int, 5, 10) // 5 是其长度,10 是其容量(可选),分别可以通过 len(sli) cap(sli) 获取

  2. slice支持append操作, 数组不支持

    c8 = append(c8, 22) //
    c2 = append(c2, 10) // err:first argument to append must be slice; have [3]int

  3. 数组赋值时会拷贝内容,slice会赋值引用和指针一样

    // 数组拷贝测试
    c1 := […]int{1, 2, 3}
    c2 := […]int{4, 5, 6}
    c3 := c2
    c2 = c1
    c2[2] = 10
    fmt.Println(“c1”, c1, len(c1), cap(c1))
    fmt.Println(“c2”, c2, len(c2), cap(c2))
    fmt.Println(“c3”, c3, len(c3), cap(c3))

    // result
    c1 [1 2 3] 3 3 // c1 没有随c2的赋值改变
    c2 [1 2 10] 3 3 // c2 拷贝了一份c1, 不同长度的数组不能拷贝
    c3 [4 5 6] 3 3 // c3 拷贝了一份c2

    // slice 拷贝测试
    c5 := []int{1, 2, 3}
    c6 := make([]int, 5, 10)
    c7 := c6
    c6 = c5
    c6[2] = 20
    fmt.Println(“c5”, c5, len(c5), cap(c5))
    fmt.Println(“c6”, c6, len(c6), cap(c6))
    fmt.Println(“c7”, c7, len(c7), cap(c7))

  1. // result
  2. c5 [1 2 20] 3 3 // c5 内容 随c6的赋值改变了
  3. c6 [1 2 20] 3 3 // c6 取得了对c5内容的引用
  4. c7 [0 0 0 0 0] 5 10 // c7 取得了对c6原来内容的引用
  1. 数组也可以进行切片,返回值是slice,改变slice时会同步修改数组内容,相当于取得这个数组的指针

    c8 := c1[:1]
    c8 = append(c8, 22)
    c8 = append(c8, 22)
    c8 = append(c8, 22)
    fmt.Println(“c1”, c1, len(c1), cap(c1))
    fmt.Println(“c8”, c8, len(c8), cap(c8))

    // result
    c1 [1 22 22] 3 3 // 数组内容发生改变,但长度不会改变
    c8 [1 22 22 22] 4 6 // slice取得了数组c1的引用

发表评论

表情:
评论列表 (有 0 条评论,272人围观)

还没有评论,来说两句吧...

相关阅读

    相关 go slice

    2.2 slice 一个slice是一个数组某个部分的引用。在内存中,它是一个包含3个域的结构体:指向slice中第一个元素的指针,slice的长度,以及slice的容量