马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
- package main
- import (
- "fmt"
- )
- func main() {
- // 创建一个字符串切片
- // 其长度和容量都是5个元素
- slice := make([]string, 5) // 如果只指定长度,那么切片的容量和长度相等。也可以分别指定长度和容量
- // 创建一个整型切片
- // 其长度为3个元素,容量为5个元素
- slice1 := make([]int, 3, 5) // 不允许创建容量小于长度的切片
- // 使用切片字面量创建切片,初始的长度和容量会基于初始化时提供的元素的个数确定
- slice2 := []string{"a", "b", "c", "d", "e"}
- // 使用切片字面量创建一个整型切片
- // 其长度和容量都是3个元素
- slice3 := []int{1, 2, 3}
- // 使用切片字面量时,可以设置初始长度和容量。要做的就是在初始化时给出所需的长度和容量作为索引
- slice4 := []string{99: ""} // 创建字符串切片,使用空字符串初始化第100个元素
- // 创建nil整型切片,只要在声明时不做任何初始化
- var slice5 []int
- // 使用make创建空的整型切片
- slice6 := make([]int, 0)
- // 使用切片字面量创建空的整型切片
- slice7 := []int{}
- // 记住,如果在[]运算符里指定了一个值,那么创建的就是数组而不是切片。只有不指定值的时候,才会创建切片
- }
复制代码
- package main
- import (
- "fmt"
- )
- func main() {
- // 创建一个整型切片
- // 其容量和长度都是5个元素
- slice := []int{1, 2, 3, 4, 5}
- // 改变索引为1的元素的值
- slice[1] = 22
- // 切片之所以被称为切片,是因为创建一个新的切片就是把底层数组切出一部分
- // 创建一个新切片
- // 其长度为2个元素,容量为4个元素
- // 切片只能访问其长度内的元素,访问超出其长度的元素将会导致运行时异常
- newSlice := slice[1:3]
- fmt.Println(len(newSlice)) // 长度 = 3 - 1
- fmt.Println(cap(newSlice)) // 容量 = 5 - 1
- // 第一个切片slice能够看到底层数组全部5个元素的容量,newSlice底层数组的容量只有4个元素
- // newSlice无法访问到它所指向的底层数组的第一个元素之前的部分
- // 修改newSlice索引为1的元素
- newSlice[1] = 33
- fmt.Println(slice[2])
- // 两个切片共享同一个底层数组,如果一个切片修改了该底层数组的共享部分,另一个切片也能感知到
- }
复制代码
- package main
- import (
- "fmt"
- )
- func main() {
- // 切片相对于数组而言,切片的好处是可以按需增加切片的容量
- // 创建一个整型切片,其长度和容量都是5个元素
- slice := []int{1, 2, 3, 4, 5}
- // 创建一个新切片,其长度为2个元素,容量为4个元素
- newSlice := slice[1:3]
- // 使用原有的容量来分配一个新元素,将新元素复制为6
- newSlice = append(newSlice, 6)
- // append操作完成后,newSlice的长度为3,容量为4
- fmt.Println(len(newSlice))
- fmt.Println(cap(newSlice))
- // 因为newSlice在底层数组里还有额外的容量可用,append操作将可用的元素合并到切片的长度,并对其进行赋值
- // 由于和原始的slice共享同一个底层数组,slice中索引为3的元素的值也被改动了
- fmt.Println(slice[3])
- // 如果切片的底层数组没有足够的可用容量,append函数会创建一个新的底层数组,将被引用的现有的值复制到新数组里,再追加新的值
- // 创建一个整型切片,其长度和容量都是4个元素
- slice2 := []int{1, 2, 3, 4}
- // 向切片追加一个新元素,将新元素赋值为5
- newSlice2 := append(slice2, 5) // 将这个append操作完成后,newSlice2拥有一个全新的底层数组,这个数组的容量是原来的两倍
- // 函数append会智能地处理底层数组的容量增长。在切片的容量小于1000个元素时,总是会成倍地增加容量。一旦超过1000个元素,容量的增长因子会设为1.25
- fmt.Println(len(newSlice2)) // 长度为5
- fmt.Println(cap(newSlice2)) // 容量为8
- }
复制代码
- package main
- import (
- "fmt"
- )
- func main() {
- // 第三个索引可以用来控制新切片的容量
- // 其目的是要限制容量
- // 创建字符串切片,其长度和容量都是5个元素
- source := []string{"a", "b", "c", "d", "e"}
- // 用第三个元素完成切片操作,创建字符串切片,并限制容量,其长度为1个元素,容量为2个元素
- slice := source[2:3:4] // 长度 = 3 - 2
- // 容量 = 4 - 2
- // 新切片里从底层数组引用了1个元素,容量是2个元素
- // 具体来说,新切片引用了c元素,并将容量扩展到d元素,如果试图设置的容量比可用的容量还大,就会报运行时错误
- // 因为内置函数append会首先使用可用容量。一旦没有可用容量,会分配一个新的底层数组。
- // 这导致很容易忘记切片间正在共享同一个底层数组。
- // 一旦发生这种情况,对切片进行修改,很可能会导致随机且奇怪的问题。
- // 对切片内容的修改会影响多个切片,却很难找到问题的原因。
- // 如果在创建切片时设置切片的容量和长度一样,就可以强制让新切片的第一个append操作创建新的底层数组,与原有的底层数组分离。
- // 新切片与原有的底层数组分离后,可以安全地进行后续修改
- // 对第三个元素做切片,并限制容量,其长度和容量都是1个元素
- slice2 := source[2:3:3]
- // 向slice2追加新字符串
- slice2 = append(slice2, "f")
- // 如果不加第三个索引,由于剩余的所有容量都属于slice2,向slice2追加f会改变原有底层数组索引为3的元素的值d
- // 因为我们限制了slice2的容量为1,当我们第一次对slice2调用append的时候,会创建一个新的底层数组
- // 这个数组包括2个元素,并将c复制进来,再追加新元素f,并返回一个引用了这个底层数组的新切片
- // 因为新的切片slice2拥有了自己的底层数组,所以杜绝了可能发生的问题
- // 我们可以继续向新切片里追加元素,而不用担心会不小心修改了其他切片里的元素
- // 同时,也保持了为切片申请新的底层数组的简洁
- }
复制代码
- package main
- import (
- "fmt"
- )
- func main() {
- // 内置函数append也是一个可变参数的函数
- // 这意味着可以在一次调用传递多个追加的值
- // 如果使用...运算符,可以将一个切片的所有元素追加到另一个切片里
- // 创建两个切片,并分别用两个整数进行初始化
- s1 := []int{1, 2}
- s2 := []int{3, 4}
- // 将两个切片追加在一起,并显示结果
- fmt.Printf("%v\n", append(s1, s2...))
- // 切片s2里的所有值都追加到了切片s1的后面
- }
复制代码
- package main
- import (
- "fmt"
- )
- func main() {
- // 迭代切片
- // 创建一个整型切片,其长度和容量都是4个元素
- slice := []int{1, 2, 3, 4}
- // 迭代每一个元素,并显示其值
- for index, value := range slice { // 如果不需要索引值,可以使用占位字符”_“来忽略这个值
- fmt.Printf("Index: %d Value: %d\n", index, value) // 使用Printf格式化输出
- }
- // 当迭代切片时,关键字range会返回两个值。第一个值是当前迭代到的索引位置,第二个值是该位置对应元素值的一个副本
- // 关键字range总是会从切片头部开始迭代。如果想对迭代做更多的控制,依旧可以使用传统的for循环
- // 从第三个元素开始迭代每个元素
- for index := 2; index < len(slice); index++ {
- fmt.Printf("Index: %d Value: %d\n", index, slice[index])
- }
- }
复制代码
- package main
- import (
- "fmt"
- )
- func main() {
- // 多维切片
- // 创建一个整型切片的切片
- slice := [][]int{{10}, {100, 200}}
- // 为第一个切片追加为20的元素
- slice[0] = append(slice[0], 20)
- }
复制代码 |