切片是一种灵活且可扩展的数据结构,用于实现和管理数据集合。切片由多个元素组成,所有元素的类型相同。切片是动态数组的一段,可以根据需要增长和收缩。与数组一样,切片是可索引的并且具有长度。切片具有容量和长度属性。
创建空切片
若要声明包含切片的变量的类型,请使用一对空方括号,后跟切片将包含的元素类型。
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
}