go切片

2018-10-02  本文已影响0人  太古汤

1.go切片实现

具体实现请参考下面的文章
Go 切片:用法和本质
总结如下:

  1. 切片可以看做一个结构体,包含len,cap,和指向底层数组的指针。其中len为切片长度,cap为容量(底层数组的空间长度)。
  2. 复制切片的时候,新生成的切片指向的数组与原有切片相同,第一个元素开始位置和len可能不同。

如s1 := []int{1,2,3}
s2 := s1
s3 := s1[1:]
s1, s2, s3底层指向的数组相同,只是第一个元素开始位置和len,cap可能不同。

  1. 在上述条件下,修改一个切片元素,会影响其他切片。

2.试验

package test

import (
    "testing"
    "fmt"
)

func TestSliceChange(t *testing.T) {
    s1 := []int{0, 1, 2, 3}
    s2 := s1
    s2[0] = 7
    fmt.Println(s1, s2)


    s3 := []int{0, 1, 2, 3}
    s4 := chSlice(s3)
    fmt.Println(s3, s4)

    s5 := make([]int, 4, 7)
    s5[0] = 0
    s5[1] = 1
    s5[2] = 2
    s5[3] = 3
    fmt.Println(s5)

    s6 := chSlice(s5)
    fmt.Println(s5, s6)
    fmt.Println(cap(s1), cap(s2), cap(s3), cap(s4), cap(s5), cap(s6))
    s6[1] = 22
    fmt.Println(s5, s6)

    s4[1] = 33
    fmt.Println(s3, s4)
}

func chSlice(s []int) []int {
  s = append(s, 9)
  return s
}

返回结果如下:

=== RUN   TestSliceChange
[7 1 2 3] [7 1 2 3]
[7 1 2 3] [7 1 2 3 9]
[0 1 2 3]
[7 1 2 3] [7 1 2 3 9]
4 4 4 8 7 7
[7 22 2 3] [7 22 2 3 9]
[7 1 2 3] [7 33 2 3 9]
--- PASS: TestSliceChange (0.00s)
PASS

其中,s3和s4由于执行append的时候,发生了扩容,返回的s4指向了一个新的数组。所以修改s4元素不会影响s3

切片作为形参

package main

import (
    "fmt"
    "testing"
)

func TestSlice(t *testing.T) {
    s := []int{2,2}
    chSlice(s)
    fmt.Println(s)

    cpSlice(s)
    fmt.Println(s)
}

func chSlice(s []int) {
    s = append(s, 1,1,1,1)
    s[0] = 10
    fmt.Println(s)
}

func cpSlice(s []int) {
    s1 := []int {3,3,3,3}
    copy(s, s1)
}

结果如下

=== RUN   TestSlice
[10 2 1 1 1 1]
[2 2]
[3 3]
--- PASS: TestSlice (0.00s)
PASS

在函数中执行append不会改变作为形参切片
但是copy函数可以改变

上一篇 下一篇

猜你喜欢

热点阅读