Go教程(六)切片

Golang中的切片是对数组的抽象和封装,切片的长度和容量不是固定的,是可以动态增加的

切片声明

var mySlice []int

字面量初始化切片

mySlice1 := []int{1, 2, 3}
fmt.Println(mySlice1)

这里和数组的区别很明显的是数组只需要在[]里面填个值就成了数组,不填,则是切片

切片运算符

与Python相同,切片可以进行切片操作

Slice[startIndex : endIndex] 将返回一个新切片

sl1 := mySlice1[0 : len(mySlice1)-1]
fmt.Println(sl1)  // [1 2]

sl1 := mySlice1[0 : len(mySlice1)]
fmt.Println(sl1)  // [1 2 3]

注意:这里的endIndex是不包含最后一个索引的,即如果是Slice[i, j],实际上返回的数据是(i, j-1),如 mySlice1[0: 2] 实际返回 [1,2]

如果需要包括最后一个数值,需要在其基础上+1,但是不能超过切片本身的长度,否则会报错

 // panic: runtime error: slice bounds out of range [:4] with capacity 3
 sl1 = mySlice1[0:4]

切片的省略写法

sl1 = mySlice[: 3] // sl1 = mySlice[0: 3]
sl1 = mySlice[2:]   // sl1 = mySlice[2: len(mySlice)]

如上所示

  • 省略:前面的值代表前端默认填0
  • 省略:后面的值,则取该切片后面所有的值

基于数组切片的相互影响

每个切片的底层都是一个数组,切片仅仅是这个底层数组的一个视图

当使用make或字面量创建切片的时候,底层数组会被自动的创建出来。

下面的代码很有意思,可以让我们加深切片的理解

// 声明和初始化一个数组
  arr := [5]int{1, 2, 3, 4, 5}
  sl1 = arr[:3] // sl1切片由该数组而来
  sl2 := arr[0:]
  fmt.Println(sl1)
  fmt.Println(sl2)
  sl1[0] = 6       // 修改切片的第1个值
  fmt.Println(sl1) //
  fmt.Println(arr) // arr的值也被修改
  fmt.Println(sl2) // sl2的值也被修改

由于上述的实验, 我们应该用切片字面量和make来创建切片,而不是像上面这样基于数组。避免修改了切片的值会影响到原来的数组

使用append动态添加数据

apppend将返回一个和原切片完全相同并且尾部追加新元素的新切片

这个新切片与原切片不同的底层数组。当append发生在原数组地址空间无法扩展时,将重新开辟一块内存,把当前的元素全部拷贝过去,再在尾部追加新元素。而这一切都是append内部发生的,所以无法确定新切片是否和老切片共享底层数组。

因此我们在append以后需要把新切片赋值给原来的切片,这样就比较安全。

sl3 := append(sl1, 4, 5) // 危险,sl3和sl1不确定是否互相影响
sl1 := append(sl1, 4, 5) // OK,还是sl1上操作

切片的零值

与数组一样,如果访问了一个未赋值的切片,则会得到它的0值

  // 声明一个切片
  var declearSlice []int
  // 打印decleareClice的原始状态
  fmt.Printf("declear clice %#v\n", declearSlice)
  // 可以直接append给nil的切片
  declearSlice = append(declearSlice, 1)
  // 再次打印该切片
  fmt.Printf("declear clice %#v\n", declearSlice)
  fmt.Println(len(declearSlice))

运行结果如下

declear clice []int(nil)
declear clice []int{1}
1

以上的实验说明go对切片进行了特殊处理,即使是nil切片也可以正常append操作

但是如果是赋值,则会发生panic

var dSlice []int
dSlice[0] = 1 // runtime error: index out of range [0] with length 0

所以append是安全的,但赋值是危险的,必须要判断该切片长度是否达标。

命令行参数切片

当我们运行程序时,主函数main是没有参数的,但是操作系统会把参数以切片的形式带过来,在golang中叫做os.Args

for index, value := range os.Args {
    fmt.Println(index, value)
  }

go run main.go first second

执行上面的代码后,我们可以得到以下的结果

0 C:\Users\ADMINI~1\AppData\Local\Temp\go-build4120744967\b001\exe\main.exe
1 first
2 second

第一个元素是程序的名称,我们从第2个元素开始取,则能得到我们自定义的参数

  for index, value := range os.Args {
    if index == 0 {
      continue
    }
    fmt.Println(index, value)
  }

修改一下代码,我们则可以看到只有

1 first
2 second
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值