golang切片
本文视频教程:https://www.bilibili.com/vide...
后面咱们学习了数组,数组是固定长度,能够包容雷同数据类型的元素的汇合。当长度固定时,应用还是带来一些限度,比方:咱们申请的长度太大节约内存,太小又不够用。
鉴于上述起因,咱们有了go语言的切片,能够把切片了解为,可变长度的数组,其实它底层就是应用数组实现的,减少了主动扩容性能。切片(Slice)是一个领有雷同类型元素的可变长度的序列。
go语言切片的语法
申明一个切片和申明一个数组相似,只有不增加长度就能够了
var identifier []type
切片是援用类型,能够应用make
函数来创立切片:
var slice1 []type = make([]type, len)也能够简写为slice1 := make([]type, len)
也能够指定容量,其中capacity为可选参数。
make([]T, length, capacity)
这里 len 是数组的长度并且也是切片的初始长度。
go语言切片实例
package mainimport "fmt"func main() { var names []string var numbers []int fmt.Printf("names: %v\n", names) fmt.Printf("numbers: %v\n", numbers) fmt.Println(names == nil) fmt.Println(numbers == nil)}
运行后果
names: []numbers: []truetrue
go语言切片的长度和容量
切片领有本人的长度和容量,咱们能够通过应用内置的len()
函数求长度,应用内置的cap()
函数求切片的容量。
实例
package mainimport "fmt"func main() { var names = []string{"tom", "kite"} var numbers = []int{1, 2, 3} fmt.Printf("len: %d cap: %d\n", len(names), cap(names)) fmt.Printf("len: %d cap: %d\n", len(numbers), cap(numbers)) var s1 = make([]string, 2, 3) fmt.Printf("len: %d cap: %d\n", len(s1), cap(s1))}
运行后果
len: 2 cap: 2len: 3 cap: 3len: 2 cap: 3
golang切片的初始化
切片的初始化办法很多,能够间接初始化,也能够应用数组初始化等。
切片如何切分
// 切片func test1() { var s1 = []int{1, 2, 3, 4, 5, 6} s2 := s1[0:3] // [) fmt.Printf("s2: %v\n", s2) s3 := s1[3:] fmt.Printf("s3: %v\n", s3) s4 := s1[2:5] fmt.Printf("s4: %v\n", s4) s5 := s1[:] fmt.Printf("s5: %v\n", s5)}
间接初始化
package mainimport "fmt"func main() { s := []int{1, 2, 3} fmt.Printf("s: %v\n", s)}
运行后果
s: [1 2 3]
应用数组初始化
package mainimport "fmt"func main() { arr := [...]int{1, 2, 3} s1 := arr[:] fmt.Printf("s1: %v\n", s1)}
运行后果
s1: [1 2 3]
应用数组的局部元素初始化(切片表达式)
切片的底层就是一个数组,所以咱们能够基于数组通过切片表达式失去切片。 切片表达式中的low和high示意一个索引范畴(左蕴含,右不蕴含),失去的切片长度=high-low,容量等于失去的切片的底层数组的容量。
package mainimport "fmt"func main() { arr := [...]int{1, 2, 3, 4, 5, 6} s1 := arr[2:5] fmt.Printf("s1: %v\n", s1) s2 := arr[2:] fmt.Printf("s2: %v\n", s2) s3 := arr[:3] fmt.Printf("s3: %v\n", s3)}
运行后果
s1: [3 4 5]s2: [3 4 5 6]s3: [1 2 3]
空(nil)切片
一个切片在未初始化之前默认为 nil,长度为 0,容量为0.
package mainimport "fmt"func main() { var s1 []int fmt.Println(s1 == nil) fmt.Printf("len: %d, cap: %d\n", len(s1), cap(s1))}
运行后果
truelen: 0, cap: 0
go语言切片的遍历
切片的遍历和数组的遍历十分相似,能够应用for循环索引遍历,或者for range循环。
for循环索引遍历
package mainimport "fmt"func main() { s1 := []int{1, 2, 3, 4, 5} for i := 0; i < len(s1); i++ { fmt.Printf("s1[%d]: %v\n", i, s1[i]) }}
运行后果
s1[0]: 1s1[1]: 2s1[2]: 3s1[3]: 4s1[4]: 5
for range循环
package mainimport "fmt"func main() { s1 := []int{1, 2, 3, 4, 5} for i, v := range s1 { fmt.Printf("s1[%d]: %v\n", i, v) }}
运行后果
s1[0]: 1s1[1]: 2s1[2]: 3s1[3]: 4s1[4]: 5
go语言切片元素的增加和删除copy
切片是一个动静数组,能够应用append()
函数增加元素,go语言中并没有删除切片元素的专用办法,咱们能够应用切片自身的个性来删除元素。因为,切片是援用类型,通过赋值的形式,会批改原有内容,go提供了copy()
函数来拷贝切片
增加元素
package mainimport "fmt"func main() { s1 := []int{} s1 = append(s1, 1) s1 = append(s1, 2) s1 = append(s1, 3, 4, 5) // 增加多个元素 fmt.Printf("s1: %v\n", s1) s3 := []int{3, 4, 5} s4 := []int{1, 2} s4 = append(s4, s3...) // 增加另外一个切片 fmt.Printf("s4: %v\n", s4)}
运行后果
s1: [1 2 3 4 5]s4: [1 2 3 4 5]
删除元素
package mainimport "fmt"func main() { s1 := []int{1, 2, 3, 4, 5} // 删除索引为2的元素 s1 = append(s1[:2], s1[3:]...) fmt.Printf("s1: %v\n", s1)}
运行后果
s1: [1 2 4 5]
公式:要从切片a中删除索引为index
的元素,操作方法是a = append(a[:index], a[index+1:]...)
拷贝切片
package mainimport "fmt"func main() { s1 := []int{1, 2, 3} s2 := s1 s1[0] = 100 fmt.Printf("s1: %v\n", s1) fmt.Printf("s2: %v\n", s2) fmt.Println("----------") s3 := make([]int, 3) copy(s3, s1) s1[0] = 1 fmt.Printf("s1: %v\n", s1) fmt.Printf("s3: %v\n", s3)}
运行后果
s1: [100 2 3]s2: [100 2 3]-------------s1: [1 2 3]s3: [100 2 3]
从运行后果,咱们看到赋值的状况下,原来的变量被批改了,应用copy函数,原来的变量没有被批改。