QQ登录

只需一步,快速开始

扫一扫,访问微社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 198|回复: 0

[技术分享] Go之旅-切片

[复制链接]

8

主题

11

帖子

1086

Z币

中级会员

Rank: 3Rank: 3

积分
1097
发表于 2018-9-20 17:25:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

  1. package main

  2. import (
  3.         "fmt"
  4. )

  5. func main() {
  6.         // 创建一个字符串切片
  7.         // 其长度和容量都是5个元素
  8.         slice := make([]string, 5) // 如果只指定长度,那么切片的容量和长度相等。也可以分别指定长度和容量
  9.         // 创建一个整型切片
  10.         // 其长度为3个元素,容量为5个元素
  11.         slice1 := make([]int, 3, 5) // 不允许创建容量小于长度的切片
  12.         // 使用切片字面量创建切片,初始的长度和容量会基于初始化时提供的元素的个数确定
  13.         slice2 := []string{"a", "b", "c", "d", "e"}
  14.         // 使用切片字面量创建一个整型切片
  15.         // 其长度和容量都是3个元素
  16.         slice3 := []int{1, 2, 3}
  17.         // 使用切片字面量时,可以设置初始长度和容量。要做的就是在初始化时给出所需的长度和容量作为索引
  18.         slice4 := []string{99: ""} // 创建字符串切片,使用空字符串初始化第100个元素
  19.         // 创建nil整型切片,只要在声明时不做任何初始化
  20.         var slice5 []int
  21.         // 使用make创建空的整型切片
  22.         slice6 := make([]int, 0)
  23.         // 使用切片字面量创建空的整型切片
  24.         slice7 := []int{}
  25.         // 记住,如果在[]运算符里指定了一个值,那么创建的就是数组而不是切片。只有不指定值的时候,才会创建切片
  26. }
复制代码

  1. package main

  2. import (
  3.         "fmt"
  4. )

  5. func main() {
  6.         // 创建一个整型切片
  7.         // 其容量和长度都是5个元素
  8.         slice := []int{1, 2, 3, 4, 5}
  9.         // 改变索引为1的元素的值
  10.         slice[1] = 22
  11.         // 切片之所以被称为切片,是因为创建一个新的切片就是把底层数组切出一部分
  12.         // 创建一个新切片
  13.         // 其长度为2个元素,容量为4个元素
  14.         // 切片只能访问其长度内的元素,访问超出其长度的元素将会导致运行时异常
  15.         newSlice := slice[1:3]
  16.         fmt.Println(len(newSlice)) // 长度 = 3 - 1
  17.         fmt.Println(cap(newSlice)) // 容量 = 5 - 1
  18.         // 第一个切片slice能够看到底层数组全部5个元素的容量,newSlice底层数组的容量只有4个元素
  19.         // newSlice无法访问到它所指向的底层数组的第一个元素之前的部分

  20.         // 修改newSlice索引为1的元素
  21.         newSlice[1] = 33
  22.         fmt.Println(slice[2])
  23.         // 两个切片共享同一个底层数组,如果一个切片修改了该底层数组的共享部分,另一个切片也能感知到
  24. }
复制代码

  1. package main

  2. import (
  3.         "fmt"
  4. )

  5. func main() {
  6.         // 切片相对于数组而言,切片的好处是可以按需增加切片的容量
  7.         // 创建一个整型切片,其长度和容量都是5个元素
  8.         slice := []int{1, 2, 3, 4, 5}
  9.         // 创建一个新切片,其长度为2个元素,容量为4个元素
  10.         newSlice := slice[1:3]
  11.         // 使用原有的容量来分配一个新元素,将新元素复制为6
  12.         newSlice = append(newSlice, 6)
  13.         // append操作完成后,newSlice的长度为3,容量为4
  14.         fmt.Println(len(newSlice))
  15.         fmt.Println(cap(newSlice))
  16.         // 因为newSlice在底层数组里还有额外的容量可用,append操作将可用的元素合并到切片的长度,并对其进行赋值
  17.         // 由于和原始的slice共享同一个底层数组,slice中索引为3的元素的值也被改动了
  18.         fmt.Println(slice[3])
  19.         // 如果切片的底层数组没有足够的可用容量,append函数会创建一个新的底层数组,将被引用的现有的值复制到新数组里,再追加新的值
  20.         // 创建一个整型切片,其长度和容量都是4个元素
  21.         slice2 := []int{1, 2, 3, 4}
  22.         // 向切片追加一个新元素,将新元素赋值为5
  23.         newSlice2 := append(slice2, 5) // 将这个append操作完成后,newSlice2拥有一个全新的底层数组,这个数组的容量是原来的两倍
  24.         // 函数append会智能地处理底层数组的容量增长。在切片的容量小于1000个元素时,总是会成倍地增加容量。一旦超过1000个元素,容量的增长因子会设为1.25
  25.         fmt.Println(len(newSlice2)) // 长度为5
  26.         fmt.Println(cap(newSlice2)) // 容量为8
  27. }
复制代码

  1. package main

  2. import (
  3.         "fmt"
  4. )

  5. func main() {
  6.         // 第三个索引可以用来控制新切片的容量
  7.         // 其目的是要限制容量
  8.         // 创建字符串切片,其长度和容量都是5个元素
  9.         source := []string{"a", "b", "c", "d", "e"}
  10.         // 用第三个元素完成切片操作,创建字符串切片,并限制容量,其长度为1个元素,容量为2个元素
  11.         slice := source[2:3:4] // 长度 = 3 - 2
  12.         // 容量 = 4 - 2
  13.         // 新切片里从底层数组引用了1个元素,容量是2个元素
  14.         // 具体来说,新切片引用了c元素,并将容量扩展到d元素,如果试图设置的容量比可用的容量还大,就会报运行时错误
  15.         // 因为内置函数append会首先使用可用容量。一旦没有可用容量,会分配一个新的底层数组。
  16.         // 这导致很容易忘记切片间正在共享同一个底层数组。
  17.         // 一旦发生这种情况,对切片进行修改,很可能会导致随机且奇怪的问题。
  18.         // 对切片内容的修改会影响多个切片,却很难找到问题的原因。
  19.         // 如果在创建切片时设置切片的容量和长度一样,就可以强制让新切片的第一个append操作创建新的底层数组,与原有的底层数组分离。
  20.         // 新切片与原有的底层数组分离后,可以安全地进行后续修改

  21.         // 对第三个元素做切片,并限制容量,其长度和容量都是1个元素
  22.         slice2 := source[2:3:3]
  23.         // 向slice2追加新字符串
  24.         slice2 = append(slice2, "f")
  25.         // 如果不加第三个索引,由于剩余的所有容量都属于slice2,向slice2追加f会改变原有底层数组索引为3的元素的值d
  26.         // 因为我们限制了slice2的容量为1,当我们第一次对slice2调用append的时候,会创建一个新的底层数组
  27.         // 这个数组包括2个元素,并将c复制进来,再追加新元素f,并返回一个引用了这个底层数组的新切片
  28.         // 因为新的切片slice2拥有了自己的底层数组,所以杜绝了可能发生的问题
  29.         // 我们可以继续向新切片里追加元素,而不用担心会不小心修改了其他切片里的元素
  30.         // 同时,也保持了为切片申请新的底层数组的简洁
  31. }
复制代码

  1. package main

  2. import (
  3.         "fmt"
  4. )

  5. func main() {
  6.         // 内置函数append也是一个可变参数的函数
  7.         // 这意味着可以在一次调用传递多个追加的值
  8.         // 如果使用...运算符,可以将一个切片的所有元素追加到另一个切片里

  9.         // 创建两个切片,并分别用两个整数进行初始化
  10.         s1 := []int{1, 2}
  11.         s2 := []int{3, 4}
  12.         // 将两个切片追加在一起,并显示结果
  13.         fmt.Printf("%v\n", append(s1, s2...))
  14.         // 切片s2里的所有值都追加到了切片s1的后面
  15. }
复制代码

  1. package main

  2. import (
  3.         "fmt"
  4. )

  5. func main() {
  6.         // 迭代切片
  7.         // 创建一个整型切片,其长度和容量都是4个元素
  8.         slice := []int{1, 2, 3, 4}
  9.         // 迭代每一个元素,并显示其值
  10.         for index, value := range slice { // 如果不需要索引值,可以使用占位字符”_“来忽略这个值
  11.                 fmt.Printf("Index: %d Value: %d\n", index, value) // 使用Printf格式化输出
  12.         }
  13.         // 当迭代切片时,关键字range会返回两个值。第一个值是当前迭代到的索引位置,第二个值是该位置对应元素值的一个副本

  14.         // 关键字range总是会从切片头部开始迭代。如果想对迭代做更多的控制,依旧可以使用传统的for循环
  15.         // 从第三个元素开始迭代每个元素
  16.         for index := 2; index < len(slice); index++ {
  17.                 fmt.Printf("Index: %d Value: %d\n", index, slice[index])
  18.         }
  19. }
复制代码

  1. package main

  2. import (
  3.         "fmt"
  4. )

  5. func main() {
  6.         // 多维切片
  7.         // 创建一个整型切片的切片
  8.         slice := [][]int{{10}, {100, 200}}
  9.         // 为第一个切片追加为20的元素
  10.         slice[0] = append(slice[0], 20)
  11. }
复制代码
*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

     
    战略合作|联系方式|广告赞助|商务合作|Archiver|手机版|小黑屋|( 京ICP备14036609号-6 )

GMT+8, 2018-12-19 12:03

© 2013-2018 Powered by Discuz! X3.3. 本站由 又拍云 提供 CDN 图片存储服务

快速回复 返回顶部 返回列表