一、基本介绍
1、切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制;
2、切片的使用和数组类似,遍历切片、访问切片的元素和求切片长度len(slice)都一样;
3、切片的长度是可以改变的,切片是一个可以动态变化数组;
4、切片定义的基本语法:
var 切片名 []类型 如 var sliceA []int
package main
import (
"fmt"
)
func main() {
//切片的基本使用
var intArr [5]int = [...]int{5, 8, 11, 44, 55}
slice1 := intArr[1:3] //slice1引用到intArr这个数组的第2个元素到第4个元素,不包括第四个元素
fmt.Println("slice元素是", slice1)
fmt.Println("slice的长度是", len(slice1))
fmt.Println("slice的容量是", cap(slice1)) //切片的容量,可以动态变化,一般为长度的两倍
}
输出
PS D:\goproject\src\go_code\chaptor7_array\demo5> go run .\main.go
slice元素是 [8 11]
slice的长度是 2
slice的容量是 4
修改切片的某个元素值,对应的数组值也会发生变化
二、切片使用的三种方式
1、定义一个切片,然后让切片去引用一个已经创建好的数组;
2、通过make来船舰切片。
基本语法: var 切片名 []type = make([]type, len, [cap])
cap指定切片容量,可选
package main
import (
"fmt"
)
func main() {
//make的使用,数组不可见,只能通过切片取访问
var slice []float64 = make([]float64, 5) //容量可选,可以不填
//对于切片必须make使用
slice[0] = 10
slice[1] = 20
fmt.Println(slice)
fmt.Println("slice的长度是", len(slice))
fmt.Println("slice的容量是", cap(slice))
}
输出
PS D:\goproject\src\go_code\chaptor7_array\demo6> go run .\main.go
[10 20 0 0 0]
slice的长度是 5
slice的容量是 5
通过make方式创建切片可以指定切片的大小和容量;
如果没有给切片的各个元素赋值,那么就会使用默认值[int,float->0, string->“”, bool->false];
通过make方式创建的切片对应的数组是由make底层维护,对外不可见,只能通过slice维护
3、定义一个切片,直接指定具体数组,类似make
var slice []int = []int {1,3,5}
package main
import (
"fmt"
)
func main() {
var strslice []string = []string{"TOM", "JACK", "MARY"}
fmt.Println(strslice)
fmt.Println("strslice的长度是", len(strslice))
fmt.Println("strslice的容量是", cap(strslice))
}
输出
PS D:\goproject\src\go_code\chaptor7_array\demo6> go run .\main.go
[TOM JACK MARY]
strslice的长度是 3
strslice的容量是 3
三、切片遍历
1、for循环
2、for range循环
package main
import (
"fmt"
)
func main() {
var arr [5]int = [...]int{10, 20, 30, 40, 50}
slice := arr[1:4] //20,30,40
//for 循环
for i := 0; i < len(slice); i++ {
fmt.Printf("slice[%v]=%v\n", i, slice[i])
}
//for range
for i, v := range slice {
fmt.Printf("i=%v, v=%v\n", i, v)
}
}
输出
PS D:\goproject\src\go_code\chaptor7_array\demo7> go run .\main.go
slice[0]=20
slice[1]=30
slice[2]=40
i=0, v=20
i=1, v=30
i=2, v=40
四、slice注意事项
1、append追加
package main
import (
"fmt"
)
func main() {
var slice1 []int = []int{100, 200, 300}
slice1 = append(slice1, 400, 500)
slice1 = append(slice1, slice1...)//只能是切片,不能是数组,...把数据拆开,不可省略
fmt.Println(slice1)
}
输出
PS D:\goproject\src\go_code\chaptor7_array\demo7> go run .\main.go
[100 200 300 400 500 100 200 300 400 500]
2、copy拷贝
copy(par1, par2): copy(slice, a),将a的值拷贝到slice中,如果slice元素多,多余部分元素值不变。slice、a两边都是slice
3、切片范围
var slice = arr[0:end] 可以简写成var slice = arr[:end]
var slice = arr[start:len(arr)]可以简写成var slice = arr[start:]
var slice = arr[0:len(arr)]可以简写成var slice = arr[:]
五、string和slice
string底层是一个byte数组,因此string也可以进行切片处理;
string是不可变的,不能通过str[0]='z’去修改字符串;
如果要修改字符串,可以先将string -> []byte /或者[]rune ->修改->重写转成string。
package main
import (
"fmt"
)
func main() {
str := "qq@com"
arr1 := []byte(str)
arr1[0] = 'z'
str = string(arr1)
fmt.Printf("str=%s\n", str)
//转成[]byte后,可以处理英文和数字,但是不能处理中文,
//[]byte字节处理,中文是3个字节,会乱码,中文需要使用rune
arr2 := []rune(str)
arr2[0] = '中'
str = string(arr2)
fmt.Printf("str=%s", str)
}
输出
PS D:\goproject\src\go_code\chaptor7_array\demo8> go run .\main.go
str=zq@com
str=中q@com
六、练习
编写一个函数fbn(n int),能够将斐波那契数列放入到切片中
package main
import (
"fmt"
)
func fbn(n int) ([]uint64) {
//声明一个切片,切片大小
fbnSlice := make([]uint64, n)
fbnSlice[0] = 1
fbnSlice[1] = 1
for i := 2; i < n; i++{
fbnSlice[i] = fbnSlice[i - 1] + fbnSlice[i - 2]
}
return fbnSlice
}
func main() {
//1、声明函数fbn(n int) ([]uint64)
//2、fbn(n int)进行for循环存放斐波那契数列
fnbSlice := fbn(10)
fmt.Println(fnbSlice)
}
输出
PS D:\goproject\src\go_code\chaptor7_array\demo9> go run .\main.go
[1 1 2 3 5 8 13 21 34 55]