golang
  • Introduction
  • 环境安装
    • vscode
    • liteide
  • 第一个Go程序
  • Go项目结构
  • Go语言命令
  • 变量
  • 数据类型
    • array
    • slice
    • map
    • struct
    • interface
    • string
    • channel
    • 类型转换
  • 循环语句
  • HTTP编程
  • init函数
Powered by GitBook
On this page
  • 简介
  • 声明语义
  • 初始化方法
  • 遍历
  • 赋值
  • 其他操作

Was this helpful?

  1. 数据类型

slice

简介

切片的数据结构可以抽象为以下3个变量:

  • 一个指向原生数组的指针(ptr)

  • 数组中的元素个数(len)

  • 数组的大小(cap)

可以使用内置函数len(slice)获取切片的元素个数,使用内置函数cap(slice)获取切片的数组大小

声明语义

go语言的切片声明后不可直接使用,还需要进行赋值。声明后的零值为nil:

var myslice []int
if myslice == nil {
    fmt.Println("myslice is nil")
}
myslice = make([]int, 5, 10) // size: 5, cap: 10
for index, _ := range myslice {
    myslice[index] = index 
}

for _, value := range myslice {
    fmt.Println(value)
}

初始化方法

  • 直接定义与初始化

如下定义一个len和cap都为3的切片

slice := []int64{2, 4, 6}
  • 使用make函数

slice1 := make([]int64, 5)    // 创建一个len与cap都为5的切片,元素初始始化为0
slice2 := make([]int64, 5, 10)    // 创建一个len为5,cap为10的切片,元素初始化为0
  • 基于数组

array := [5]int64{2, 4, 6, 8, 10}
slice := array[3:]    // (*)

这里需要详细说明一下(*)这一行代码。这一行代码会创建一个切片,但切片的底层数组使用的是变量array,切片的指针是数组的第三个元素,也就是说该行代码并没有申请一个新的空间给切片元素;由于数组的大小为5,所以切片的len与cap都会初始化为3。

此时,当我们更改切片元素的值,数组的值也会相应变化。看如下代码与输出:

array := [5]int64{2, 4, 6, 8, 10}
slice := array[3:]    

for i := 0; i < len(slice); i++ {
    slice[i] = slice * 2
}

for i := 0; i < len(array); i++ {
    fmt.Println(array[i])
}

输出如下:

2
4
12
16
20

当然,当我们继续往切片中添加元素,直到元素个数超出3个时,此时会为切片分配一个新的空间,这时修改切片的值就不会对原数组产生影响

遍历

len()函数可以得到切片的长度,cap()函数可以得到切片的空间。也可以用for ... range ...来遍历切片

slice := []string{"one", "two", "three"}
for index, value := range arr {
    fmt.Printf("index = %d, value = %s\n", index, value)
}

赋值

由于切片是一个内置类型,所以赋值操作与函数的参数传递都是go语言预定义好的。

  • 赋值

切片的赋值相当于把右边切片的三个变量(prt、len、cap)赋值给左边切片,也就是说,赋值后两个切片使用的是同一个底层数组,且两个切片的len与cap也都一样。看下来的代码:

slice1 := []int64{1, 2, 3}
slice2 := []int64{4}
slice2 = slice1
slice2[0] = 5
fmt.Println(slice1)
fmt.Println(slice2)

输出:

[5 2 3]
[5 2 3]

当然,如果先赋值,再扩容,那么两个切片就不会相互影响,这是因为扩容后新的切片已经分配了新的内存空间,两个切片就不共享底层数组了,看如下代码:

slice1 := []int64{1, 2, 3}
slice2 := []int64{4}
slice2 = slice1
slice2 = append(slice2, 4, 5)
slice2[0] = 0
fmt.Println(slice1)
fmt.Println(slice2)

输出如下:

[1 2 3]
[0 2 3 4 5]

其他操作

  • 添加元素

切片可以动态扩展,当cap - len(即剩余空间)不足以容纳新元素的个数时,此时会重新分配一个新的空间,把原来空间的元素拷贝过来,然后再添加新的元素。

切片的动态扩展使用内置函数append(),使用如下:

slice := []int64{1, 2, 3}
slice = append(slice, 4, 5)    // 添加4,5两个元素
  • 删除元素

PreviousarrayNextmap

Last updated 5 years ago

Was this helpful?