官术网_书友最值得收藏!

Slices

You'll not find the concept of slice in many programming languages, despite the fact that it is both smart and handy. A slice has many similarities with an array, and it allows you to overcome the shortcomings of an array.

Slices have a capacity and length property, which are not always the same. The length of a slice is the same as the length of an array with the same number of elements and can be found using the len() function. The capacity of a slice is the current room that has been allocated for this particular slice and can be found with the cap() function. As slices are dynamic in size, if a slice runs out of room, Go automatically doubles its current length to make room for more elements.

As slices are passed by reference to functions, any modifications you make to a slice inside a function will not be lost after the function ends. Additionally, passing a big slice to a function is significantly faster than passing the same array because Go will not have to make a copy of the slice; it will just pass the memory address of the slice variable.

The code of this subsection is saved in slices.go, and it can be separated into three main parts.

The first part is the preamble as well as the definition of two functions that get slice as input:

package main 
 
import ( 
   "fmt" 
) 
 
func change(x []int) { 
   x[3] = -2 
} 
 
func printSlice(x []int) { 
   for _, number := range x {

fmt.Printf("%d ", number) } fmt.Println() }

Note that when you use range over a slice, you get a pair of values in its iteration. The first one is the index number and the second one is the value of the element. When you are only interested in the stored element, you can ignore the index number as it happens with the printSlice() function.

The change() function just changes the fourth element of the input slice, whereas printSlice() is a utility function that prints the contents of its slice input variable. Here, you can also see the use of the fmt.Printf() function for printing an integer number.

The second part creates a new slice named aSlice and makes a change to it with the help of the change() function you saw in the first part:

func main() { 
   aSlice := []int{-1, 4, 5, 0, 7, 9} 
   fmt.Printf("Before change: ") 
   printSlice(aSlice) 
   change(aSlice) 
   fmt.Printf("After change: ") 
   printSlice(aSlice) 

Although the way you define a populated slice has some similarities with the way you define an array, the biggest difference is that you do not have to declare the number of elements your slice will have.

The last part illustrates the capacity property of a Go slice as well as the make() function:

   fmt.Printf("Before. Cap: %d, length: %d\n", cap(aSlice), len(aSlice)) 
   aSlice = append(aSlice, -100) 
   fmt.Printf("After. Cap: %d, length: %d\n", cap(aSlice), len(aSlice)) 
   printSlice(aSlice) 
   anotherSlice := make([]int, 4) 
   fmt.Printf("A new slice with 4 elements: ") 
   printSlice(anotherSlice) 
} 

The make() function automatically initializes the elements of a slice to the zero value for that type, which can be verified by the output of the printSlice (anotherSlice) statement. Note that you need to specify the number of elements of a slice when you create it with the make() function.

Executing slices.go generates the following output:

$ go run slices.go 
Before change: -1 4 5 0 7 9 
After change: -1 4 5 -2 7 9 
Before. Cap: 6, length: 6 
After. Cap: 12, length: 7 
-1 4 5 -2 7 9 -100 
A new slice with 4 elements: 0 0 0 0 

As you can see from the third line of the output, the capacity and the length of a slice were the same at the time of its definition. However, after adding a new element to the slice using append(), its length goes from 6 to 7 but its capacity doubles and goes from 6 to 12. The main advantage you get from doubling the capacity of a slice is better performance because Go will not have to allocate memory space all the time.

You can create a slice from the elements of an existing array, and you can copy an existing slice to another one using the copy() function. Both operations have some tricky points, and you should experiment with them.

Chapter 6, File Input and Output, will talk about a special type of slice, named byte slice, that can be used in file I/O operations.

主站蜘蛛池模板: 来安县| 高碑店市| 天台县| 微山县| 平谷区| 加查县| 凤城市| 罗山县| 宣威市| 平谷区| 射阳县| 巴东县| 昭觉县| 平果县| 平陆县| 高尔夫| 沈阳市| 扶沟县| 临沭县| 宁阳县| 乐平市| 奈曼旗| 长子县| 公主岭市| 洛浦县| 石河子市| 石泉县| 四会市| 崇仁县| 万全县| 江达县| 滕州市| 达尔| 泸溪县| 竹北市| 平原县| 托里县| 奉新县| 巴马| 万安县| 平塘县|