Detailed go language array and slice [two]

Detailed go language array and slice [two]

  Previous   Detailed go language array and slice [A] has been explained before, some of the basic usage and slice the array, you need to pay attention when using array slice and, in particular, more local slice that need attention. It will be used when the last one to create a new slice explain third slice indices to limit the capacity of the new slice in operation, if the capacity is greater than the length of a new slice, add a new element is still change after the corresponding source elements. This is one where I will explain how to avoid these problems, as well as iterative, and as knowledge parameters of the method.

The length and capacity of the slice is set to the same value

  If you create a new slice when we set the value of his length and capacity for the kind of value, when append a new element, the bottom will create a new array and copy the values ​​of the past before. This will not affect the common underlying array before.

    // 创建一个容量和长度均为6的slice
    slice1 := []int{5, 23, 10, 2, 61, 33}
    // 对slices1进行切片,长度为2容量为3
    slice2 := slice1[1:3:3]
    fmt.Println("cap", cap(slice2))
    fmt.Println("slice2", slice2)

    //修改一个共同指向的元素
    //两个slice的值都会修改
    slice2[0] = 11111
    fmt.Println("slice1", slice1)
    fmt.Println("slice2", slice2)

    // 增加一个元素
    slice2 = append(slice2, 55555)

    fmt.Println("slice1: ", slice1)
    fmt.Println("slice2: ", slice2)

  Output

cap 2
slice2 [23 10]
slice1 [5 11111 10 2 61 33]
slice2 [11111 10]
slice1:  [5 11111 10 2 61 33]
slice2:  [11111 10 55555]

  The code is the same length and capacity, calculated length and capacity to see my previous blog. After an additional element, the original common underlying data points is not changed. Because the underlying array slice2 was reassigned a.

Iteration slice

  go language built a set of keywords for iteration range, of course, he can also be an iterative slice, you can use _ to ignore the elements we do not care, but if you only care about the index so you do not need to write for index, _: = range slice1. The complete code is given

    // 创建一个容量和长度均为6的slice
    slice1 := []int{5, 23, 10, 2, 61, 33}

    for index, value := range slice1 {
        fmt.Println("index: ", index, " value: ", value)
    }

    // 可以忽略我们不关心的元素
    // 只关心value
    for _, value := range slice1 {
        fmt.Println("value ", value)
    }

    // 只关心index, 可以不用 _
    for index := range slice1 {
        fmt.Println("index: ", index)
    }

 

   Note that rang iterative value and value is a replica, we can compare the address value of the corresponding index in the iterative value and the original slice:

    // 创建一个容量和长度均为6的slice
    slice1 := []int{5, 23, 10, 2, 61, 33}

    for index, value := range slice1 {
        fmt.Println("index: ", index, " value address : ", &value, " slice1 value address", &slice1[index])

    }

  Output

index:  0  value address :  0xc04204e088  slice1 value address 0xc04206a030
index:  1  value address :  0xc04204e088  slice1 value address 0xc04206a038
index:  2  value address :  0xc04204e088  slice1 value address 0xc04206a040
index:  3  value address :  0xc04204e088  slice1 value address 0xc04206a048
index:  4  value address :  0xc04204e088  slice1 value address 0xc04206a050
index:  5  value address :  0xc04204e088  slice1 value address 0xc04206a058

  slice1 in the value of the address is constantly changing. The address value does not change the value of the iteration, because the value is a variable, different values ​​for the time iteration. We write the code below so that you will be clear

    var index, value int
    for index, value = range slice1 {
        fmt.Println("index: ", index, &index, " value address : ", &value, " slice1 value address", &slice1[index])

    }

   In addition to using rang you can also use a traditional for loop iterations to do

    slice1 := []int{5, 23, 10, 2, 61, 33}
    
    for i, len := 1, len(slice1); i < len; i++ {
        fmt.Println("index: ", i, " value:", slice1[i])
    }

 

 slice as a parameter

   Because of the special structure of the slice, there is a pointer to an array

    s := make([]int, 2, 5)
    fmt.Println("len: ", len(s))
    fmt.Println("cap: ", cap(s))
    s = append(s, 2)

    s[0] = 12

 

  So, slice passed as a parameter method will only copy the slice itself does not copy the underlying array slice. If we create an int type has slice 100 Wan length, pass him to a method, you only need to copy 24 bytes is enough. Pointer requires 8, 8 are the length and capacity.

const size int = 1000 * 1000

func main() {
    slice0 := make([]int, size)
    fmt.Println("slice0 len: ", len(slice0), " cap :", cap(slice0))
    doSomeThing(slice0)
}

func doSomeThing(s []int) {
    fmt.Println(len(s))
}

 

 

@ 2017-09-20 11:34. Posted lpxxn read (...) Comments (...) edit collections

Guess you like

Origin blog.csdn.net/mi_duo/article/details/86140421