切片是一种灵活且可扩展的数据结构,用于实现和管理数据集合。切片由多个元素组成,所有元素的类型相同。切片是动态数组的一段,可以根据需要增长和收缩。与数组一样,切片是可索引的并且具有长度。切片具有容量和长度属性。

 

创建空切片

若要声明包含切片的变量的类型,请使用一对空方括号,后跟切片将包含的元素类型。

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var intSlice []int
	var strSlice []string

	fmt.Println(reflect.ValueOf(intSlice).Kind())
	fmt.Println(reflect.ValueOf(strSlice).Kind())
}

输出

slice
slice

 

使用make声明切片

Slice可以使用内置函数make创建。使用make时,一个选项是指定切片的长度。仅指定长度时,切片的容量是相同的。

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var intSlice = make([]int, 10)        // 切片长度和容量相同
	var strSlice = make([]string, 10, 20) // 切片长度和容量不同,20是容量

	fmt.Printf("intSlice \tLen: %v \tCap: %v\n", len(intSlice), cap(intSlice))
	fmt.Println(reflect.ValueOf(intSlice).Kind())

	fmt.Printf("strSlice \tLen: %v \tCap: %v\n", len(strSlice), cap(strSlice))
	fmt.Println(reflect.ValueOf(strSlice).Kind())
}

输出

intSlice        Len: 10         Cap: 10
slice
strSlice        Len: 10         Cap: 20
slice

 

值初始化切片

使用空括号,后跟切片将包含的元素类型,以及每个元素在大括号中具有的初始值的列表。

package main

import "fmt"

func main() {
	var intSlice = []int{10, 20, 30, 40}
	var strSlice = []string{"India", "Canada", "Japan"}

	fmt.Printf("intSlice \tLen: %v \tCap: %v\n", len(intSlice), cap(intSlice))
	fmt.Printf("strSlice \tLen: %v \tCap: %v\n", len(strSlice), cap(strSlice))
}

 

使用new关键字声明切片

可以使用new关键字声明切片,后跟方括号中的容量,然后是切片将包含的元素类型。

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var intSlice = new([50]int)[0:10]

	fmt.Println(reflect.ValueOf(intSlice).Kind())
	fmt.Printf("intSlice \tLen: %v \tCap: %v\n", len(intSlice), cap(intSlice))
	fmt.Println(intSlice)
}

输出

slice
intSlice        Len: 10         Cap: 50
[0 0 0 0 0 0 0 0 0 0]

 

添加元素

若要将项添加到切片的末尾,请使用append()方法。

package main

import "fmt"

func main() {
	a := make([]int, 2, 5)
	a[0] = 10
	a[1] = 20
	fmt.Println("Slice A:", a)
	fmt.Printf("Length is %d Capacity is %d\n", len(a), cap(a))

	a = append(a, 30, 40, 50, 60, 70, 80, 90)
	fmt.Println("Slice A after appending data:", a)
	fmt.Printf("Length is %d Capacity is %d\n", len(a), cap(a))
}

输出

Slice A: [10 20]
Length is 2 Capacity is 5
Slice A after appending data: [10 20 30 40 50 60 70 80 90]
Length is 9 Capacity is 12

如果基础切片中有足够的容量,则该元素将放置在最后一个元素之后,并且长度将增加。但是,如果容量不足,则会创建一个新切片,复制所有现有元素,将新元素添加到末尾,并返回新切片。

 

访问元素

您可以通过引用索引号来访问切片项目。

package main

import "fmt"

func main() {
	var intSlice = []int{10, 20, 30, 40}

	fmt.Println(intSlice[0])
	fmt.Println(intSlice[1])
	fmt.Println(intSlice[0:4])
}

 

更改元素值

package main

import "fmt"

func main() {
	var strSlice = []string{"India", "Canada", "Japan"}
	fmt.Println(strSlice)

	strSlice[2] = "Germany"
	fmt.Println(strSlice)
}

输出

[India Canada Japan]
[India Canada Germany]

 

从切片中删除元素

删除索引函数创建以从字符串切片中删除特定元素。

package main

import "fmt"

func main() {
	var strSlice = []string{"India", "Canada", "Japan", "Germany", "Italy"}
	fmt.Println(strSlice)

	strSlice = RemoveIndex(strSlice, 3)
	fmt.Println(strSlice)
}

func RemoveIndex(s []string, index int) []string {
	return append(s[:index], s[index+1:]...)
}

输出

[India Canada Japan Germany Italy]
[India Canada Japan Italy]

 

复制切片

内置的copy功能用于将数据从一个切片复制到另一个切片。

package main

import "fmt"

func main() {
	a := []int{5, 6, 7} // Create a smaller slice
	fmt.Printf("[Slice:A] Length is %d Capacity is %d\n", len(a), cap(a))

	b := make([]int, 5, 10) // Create a bigger slice
	copy(b, a)              // Copy function
	fmt.Printf("[Slice:B] Length is %d Capacity is %d\n", len(b), cap(b))

	fmt.Println("Slice B after copying:", b)
	b[3] = 8
	b[4] = 9
	fmt.Println("Slice B after adding elements:", b)
}

输出

[Slice:A] Length is 3 Capacity is 3
[Slice:B] Length is 5 Capacity is 10
Slice B after copying: [5 6 7 0 0]
Slice B after adding elements: [5 6 7 8 9]

 

切片的技巧

切片是一种有条不紊地访问部分数据的快速方法。

package main

import "fmt"

func main() {
	var countries = []string{"india", "japan", "canada", "australia", "russia"}

	fmt.Printf("Countries: %v\n", countries)

	fmt.Printf(":2 %v\n", countries[:2])

	fmt.Printf("1:3 %v\n", countries[1:3])

	fmt.Printf("2: %v\n", countries[2:])

	fmt.Printf("2:5 %v\n", countries[2:5])

	fmt.Printf("0:3 %v\n", countries[0:3])

	fmt.Printf("Last element: %v\n", countries[4])
	fmt.Printf("Last element: %v\n", countries[len(countries)-1])
	fmt.Printf("Last element: %v\n", countries[4:])

	fmt.Printf("All elements: %v\n", countries[0:len(countries)])

	fmt.Printf("Last two elements: %v\n", countries[3:len(countries)])
	fmt.Printf("Last two elements: %v\n", countries[len(countries)-2:len(countries)])

	fmt.Println(countries[:])
	fmt.Println(countries[0:])
	fmt.Println(countries[0:len(countries)])
}

输出

Countries: [india japan canada australia russia]
:2 [india japan]
1:3 [japan canada]
2: [canada australia russia]
2:5 [canada australia russia]
0:3 [india japan canada]
Last element: russia
Last element: russia
Last element: [russia]
All elements: [india japan canada australia russia]
Last two elements: [australia russia]
Last two elements: [australia russia]
[india japan canada australia russia]
[india japan canada australia russia]
[india japan canada australia russia]

 

循环访问切片

可以使用for循环遍历列表项。

package main

import "fmt"

func main() {
	var strSlice = []string{"India", "Canada", "Japan", "Germany", "Italy"}

	fmt.Println("\n---------------Example 1 --------------------\n")
	for index, element := range strSlice {
		fmt.Println(index, "--", element)
	}

	fmt.Println("\n---------------Example 2 --------------------\n")
	for _, value := range strSlice {
		fmt.Println(value)
	}

	j := 0
	fmt.Println("\n---------------Example 3 --------------------\n")
	for range strSlice {
		fmt.Println(strSlice[j])
		j++
	}
}

 

将切片追加到现有切片

...用于追加切片的省略号。

package main

import "fmt"

func main() {
	var slice1 = []string{"india", "japan", "canada"}
	var slice2 = []string{"australia", "russia"}

	slice2 = append(slice2, slice1...)
}

 

检查元素是否存在

要确定切片中是否存在指定的项,请迭代切片项并检查使用if条件。

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var strSlice = []string{"India", "Canada", "Japan", "Germany", "Italy"}
	fmt.Println(itemExists(strSlice, "Canada"))
	fmt.Println(itemExists(strSlice, "Africa"))
}

func itemExists(slice interface{}, item interface{}) bool {
	s := reflect.ValueOf(slice)

	if s.Kind() != reflect.Slice {
		panic("Invalid data-type")
	}

	for i := 0; i < s.Len(); i++ {
		if s.Index(i).Interface() == item {
			return true
		}
	}

	return false
}