Go-slice

Variable-length sequences with elements of the same type. Usually written as [] T, the element type is T, and you can access some or all elements of the array. This array is called the slice bottom array.

Attributes

Slice has three attributes: pointer, length and capacity.

The pointer points to the first element of the array that can be accessed from the slice.

The length is the number of elements in the slice, and cannot exceed the capacity of the slice.

The capacity is the number of elements from the start element of the slice to the last element of the underlying array.

 

The slice operator s [i: j] (where i <= j <= cap (s)) creates a new slilce, referencing all elements in the sequence S from i to j-1 index position.

S can be an array, a pointer to an array, or a slice.

If i is omitted from the expression, i = 0; if j is omitted, then j = len (s)

 

Because slices contain pointers to arrays, passing a slice to a function allows you to modify the elements of the underlying array inside the function.

//就地反转一个整型slice中的元素
func reverse (s []int){
    for i,j := 0,len(s) - 1; i, j = i +1, j -1 {
        s[i], s[j] = s[j], s[i]
    }
}

a := [...]int{0,1,2,3,4,5}
reverse( a[:] )

Initialize slice

A sequence of elements separated by commas and enclosed in curly braces, but the slice does not specify a length.

How to initialize the slice:

//方法1:用make
var s1 []string = make([]string, 0) 
var s2 []string = make([]string, 1) 
var s3 []string = make([]string, 20)

方法2:静态显式初始化
var s1 []string = []string {}
var s2 []string = []string{"aa"} 
var s3 []string = []string{"aa", "bb", "cc"} 

var s4 = []string{} 
var s5 = []string{"aa"} 
var s6 = []string{"aa", "bb", "cc"} 

s7 := []string{} 
s8 := []string{"aa"} 
s9 := []string{"aa", "bb", "cc"}

The difference is to create an array of intrinsic length and  a slice pointing to the array .

 

Slices cannot be compared because you cannot use == to test whether two slices have the same element. The standard library provides bytes.Equal to compare two bytes slice ([] byte).

String slice comparison:

func equal (x,y []string) bool{

    if len(x) != len(y){
        return false
    }

    for i := 0; i < len(x); i++{
        if x[i] !=y[i]
        return false
    }
    return true
}

Why can't you just compare with ==?

1. The slice element is indirect and may contain itself;

2. If the underlying array elements change, the same slice will have different elements at different times . Since the hash table only makes shallow copies of the keys of the elements, this requires that the keys in the hash table must remain unchanged throughout the life of the hash table . Because slices need to be compared in depth, slices cannot be used as map keys .

nil value comparison

The only comparison operator allowed for slices is to compare with nil. The zero value of slice type is nil, indicating that there is no corresponding underlying array;

The length and capacity of a slice of nil value is 0;

There are also slices with non-nil values ​​whose length and capacity are 0, for example, [] int {} or make ([] int, 3) [3:];

For any type, if their value can be nil, then this type of nil value, you can use a conversion expression, such as: [] int (nil)

var s []int     //len(s) == 0, s == nil
s = nil         //len(s) == 0, s== nil
s = []int(nil)  //len(s) == 0, s == nil
s = []int{}     //len(s) == 0, s != nil

To check if a slice is empty, use len (s) == 0, instead of s == nil

 

The built-in function make can create a slice that specifies the element type, length and capacity. The capacity parameter can be omitted, in which case the length and capacity are equal.

make ([]T,len)

make([]T, len, cap)

make creates an unnamed array and returns a slice of it. This array can only be accessed through this slice.

//为rune类型添加元素,追加到slice后面:

var runes []rune
for _,r := range "Hello,世界"{
    runes = append(runes, r)
}

fmt.Printf("%q\n", runes)

//最方便的用法是 []rune("Hello,世界")

Analysis: slice adds elements

func appendInt (x []int, y int) []int{

    var z []int
    zlen := len(x) + 1

    if zlen < cap(x){
        //slice仍有增长空间,扩展slice内容
        z = x[:len]
    } else{
        //slice已无空间容量, 分配一个新的底层数组
        zcap := zlen
        if zcap < 2 * len(x){
            zcap = 2 * len(x)
        }

        z = make([]int, zlen, zcap)
        copy(z, x) //内置copy函数
    }

    z[len(x)] = y
    return z
}

Enough capacity : define a new slice (still referencing the original underlying array), copy the new element to a new location, and return the new slice.

[New slice pointing to the original underlying array]

Insufficient capacity : You must create a new underlying array with sufficient capacity, then copy the elements from the original slice to this array, and then append y to the back of the array.

[New lsice pointing to the new underlying array]

copy function

The first parameter is the target slice, and the second parameter is the original slice.

Return value: Returns the number of elements actually copied. This value is the value of the two slices with a smaller length.

Traverse

slice := []int{0, 1, 2, 3}
for k,v :=range slice{
    fmt.Println("k:",k,"v:",v)
}

The content traversed by for range is a copy of the original content, so it cannot be used to modify the content in the original slice;

If you want to modify the value of the original slice, you need to use k to modify directly according to the index position:

for k,v :=range slice{
    if v==1 {
        slice[k]=100
    }
}

 

Published 127 original articles · Likes 24 · Visits 130,000+

Guess you like

Origin blog.csdn.net/Linzhongyilisha/article/details/99687389