切片 Slices
Slices reference arrays, slices is kind of a view into array.
Definition
与 Javascript 中的 Array
, python 中的 list
类似,唯一不同的是 Golang 中的 Slice
拥有固定长度。
Example: [2, 3, 1]
with index [0, 1, 2]。
在 Golang 中 type 是 [3]int
, an array of three integers。
var myInts [10]int
primes := [6]int{2, 3, 5, 7, 11, 13}
func getMessageWithRetries() [3]string {
return [3]string {
"click here to sign up",
"pretty please click here",
"we beg you to sign up",
}
}
Slice in Go
99times out of 100 you will use a slice instead of an array when working with ordered lists.
Arrays are fiexed in size. Once you make an array like [10]int
you can't add an 11th element.
A slice is dynamically-sized, flexible view of the elements of an array.
Slices always have an underlying array, though it isn't always spcified explicityly. To explicityly create a slice on top of an array we can do:
primes := [6]int{2, 3, 5, 7, 11, 13}
mySlice := primes[1:4]
// mySlice = {3, 5, 7}
The syntax is:
arrayname[lowIndex:highIndex]
arrayname[lowIndex:]
arrayname[:highIndex]
arrayname[:]
Make
Definition
Most of the tiem we don't need to think about underlying array of a slice. We can create a new slice using the make
function:
// func make([]T, len, cap) []T
mySlice := make([]int, 5, 10)
// The capacity argument is usually omitted and defaults to the length
mySlice := make([]int, 5)
Slices created with make
will be filled with the zero value of the type.
If we want to create a slice with a specific set of values, we can use a slice literal:
mySlice := []string{"I", "love", "Go"}
Note that the array brackets do not have a 3
in them. If they did, you'd have an array instead of a slice.
Assignment
func getMessageCosts(messages []string) []float64 {
costs := make([]float64, len(messages))
if i := 0; i < len(messages); i++ {
message := messages[i]
cost := float64(len(message)) * 0.01
costs[i] = cost
}
return costs
}
Length
The length of a lsice is simply the number of elements it contains. It is accessed using the built-in len()
function.
mySlice := []string{"I", "love", "Go"}
fmt.Println(len(mySlice)) // 3
Capacity
The capacity of a slice is the number of elements in the underlying array, counting from the first element in first element in the slice. It is accessed using the built-in cap()
function:
mySlice := []string{"I", "love", "Go"}
fmt.Println(cap(mySlice)) // 3
Unless you're hyper-optimizing the memory usage of your program, you don't need to worry about the capacity of a slice because it will automatically grow as needed.
underlying principle (When a slice grow the size)
可变参数 Variadic
增加 Append
The built-in append function is used to dynamically add elements to a slice:
func append(slice []Type, elems ...Type) []Type
If the underlying array is not large enough, append()
will create a new underlying array and point the slice to it.
Notice that append()
is variadic, the following are all valid:
slice = append(slice, oneThing)
slice = append(slice, firstThing, secondThing)
slice = append(slice, anotherSlice...)
Assignment
type Cost struct {
day int
value float64
}
func getCostsByDay(costs []cost) []float64 {
costsByDay := []float64{}
for i := 0; i< len(cost); i++ {
cost := costs[i]
if cost.day >= len(costsByDay) {
costsByDay = append(costsByDay, 0.0)
}
costsByDay[cost.day] += cost.value
}
return costsByDay
}
Slice of slices
Slices can hold other slices, effectively creating a matrix, or a 2D slice.
rows := [][]int{}
func createMatrix(rows, cols int) [][]uint {
matrix := make([][]int, 0)
for i := 0; i < rows; i++ {
row := make ([]int, 0)
for j := 0; j < cols; j++ {
row = append(row, i*j)
}
matrix = append(matrix, row)
}
}
Tricky slices
The append()
function chnages the underlying array of its parameter AND returns a new slice. This means that using append()
on anything other than itself is usually a BAD idea.
// don't do this !
someSLice = append(otherSlice, element)
Range
Go provides syntactic suger to iterate easily over elements of slice:
for INDEX, ELEMENT := range SLICE {
}
fruits := []string{"apple", "banana", "grape"}
for i, fruit := range fruits {
fmt.Prinln(i, fruit)
}
// 0 apple
// 1 banana
// 2 grape