kevinyan815 / gocookbook

go cook book
MIT License
789 stars 167 forks source link

Slice追加和删除元素 #4

Open kevinyan815 opened 5 years ago

kevinyan815 commented 5 years ago

向切片追加新元素

使用append向切片追加元素, 其声明为func append(s[]T, vs ...T) []Tappend 方法将 0 个或多个具有相同类型的元素追加到切片s后面并且返回新的切片;追加的元素必须和原切片的元素同类型。如果 s 的容量不足以存储新增元素,append 会分配新的切片来保证已有切片元素和新增元素的存储。因此,返回的切片可能已经指向一个不同的相关数组了。append 方法总是返回成功,除非系统内存耗尽了。

It is common to append new elements to a slice, and so Go provides a built-in append function. The documentation of the built-in package describes append. func append(s []T, vs ...T) []T The first parameter s of append is a slice of type T, and the rest are T values to append to the slice. The resulting value of append is a slice containing all the elements of the original slice plus the provided values. If the backing array of s is too small to fit all the given values a bigger array will be allocated. The returned slice will point to the newly allocated array.


package main

import "fmt"

func main() { var s []int printSlice(s)

// append works on nil slices.
s = append(s, 0)
printSlice(s)

// The slice grows as needed.
s = append(s, 1)
printSlice(s)

// We can add more than one element at a time.
s = append(s, 2, 3, 4)
printSlice(s)

}

func printSlice(s []int) { fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s) }

### 向nil slice追加元素不会引发运行时错误(append a nil slice is OK)

因为`append`方法返回新的切片,所以可以向未初始化的nil slice追加元素,append会分配新切片存储元素并返回新切片,不会引起像给未初始化的nil map赋值时引发的运行时错误。
>nil map doesn't point to an initialized map. Assigning value won't reallocate point address.
The append function appends the elements x to the end of the slice s, and grows the slice if a greater capacity is needed.  It reallocates the resulting slice describes a completely different array.

### 删除切片中的元素(Delete element in a slice)

Let we say `a` is the slice, and `i` is the index of the element you want to delete:

a = append(a[:i], a[i+1:]...)



`...` is syntax for variadic arguments in Go.

Basically, when defining a function it puts all the arguments that you pass into one slice of that type. By doing that, you can pass as many arguments as you want (for example, fmt.Println can take as many arguments as you want).

Now, when calling a function, ... does the opposite: it unpacks a slice and passes them as separate arguments to a variadic function.

[Source in stackoverflow](https://stackoverflow.com/questions/25025409/delete-element-in-a-slice)

Note: If `a` is a single element slice,  `a = append(a[:i], a[i+1:]...)` will cause run time panic error:" slice bounds out of range."