美文网首页
Golang:切片的底层详解和初步使用

Golang:切片的底层详解和初步使用

作者: 金刀大菜牙 | 来源:发表于2020-09-24 23:40 被阅读0次

什么是切片

切片是 Golang 中比较特殊的数据结构,这种数据结构更便于使用和管理数据集合。简单的说,切片就是一种简化版的动态数组。因为动态数组的长度不固定,所以切片的长度自然也就不能是类型的组成部分了。切片是围绕动态数组的概念构建的,是对数组的抽象。数组虽然有适用的地方,但是数组的类型和操作都不够灵活,因此在 Go 代码中数组使用的并不是很多,而切片则使用的相当广泛,理解切片的原理和用法相当重要。

切片的内部结构

我们先来看看切片的结构定义,即 reflect.SliceHeader:

type SliceHeader struct {
    Data uintptr
    Len int
    Cap int
}

由切片的结构定义可知,切片的结构由三个信息组成:

  1. 指针,指向底层数组中切片指定的开始位置

  2. 长度,即切片的长度

  3. 最大长度,也就是切片开始位置到数组的最后位置的长度

下图给出了切片 x := [2, 3, 5, 7, 9, 11, 13, 15] 和 y := [1:3] 两个切片对应的内存结构。

切片底层结构图.png

切片的创建和初始化

让我们看看切片有哪些创建和初始化的方式:

var(
  a []int // nil 切片,和 nil 相等,一般用来表示一个不存在的切片
  b = []int{} // 空切片,和 nil 不相等,一般用来表示一个空的集合  
  c = []int{1, 2, 3, 4} // 有 4 个元素的切片,len 和 cap 都为 4
  d = c[:2] // 有 2 个元素的切片,len 为 2,cap 为 4
  e = c[0:2:cap(c)] // 有 2 个元素的切片,len 为 2,cap 为 4
  f = c[:0] // 有 0 个元素的切片,len 为 0,cap 为 4
  g = make([]int, 3) // 有 3 个元素的切片,len 和 cap 都为 3
  h = make([]int, 3, 5) // 有 3 个元素的切片,len 为 3,cap 为 5
  i = make([]int, 0, 5) // 有 0 个元素的切片,len 为 0,cap 为 5
)

使用 Golang 内置的函数 len() 可以查看切片中有效元素的长度,内置的函数 cap() 可以查看切片容量大小。

切片 len() 和 cap().png

修改切片

切片没有自己的任何数据,它只是底层数组的一个表示。对切片所做的任何修改都将反映在底层数组中。

示例代码:

package main

import (  
    "fmt"
)

func main() {  
    darr := [...]int{57, 89, 90, 82, 100, 78, 67, 69, 59}
    dslice := darr[2:5]
    fmt.Println("array before",darr)
    for i := range dslice {
        dslice[i]++
    }
    fmt.Println("array after",darr) 
}

运行结果:

array before [57 89 90 82 100 78 67 69 59]  
array after [57 89 91 83 101 78 67 69 59] 

当多个片共享相同的底层数组时,每个元素所做的更改将在数组中反映出来。

示例代码:

package main

import (  
    "fmt"
)

func main() {  
    numa := [3]int{78, 79 ,80}
    nums1 := numa[:] //creates a slice which contains all elements of the array
    nums2 := numa[:]
    fmt.Println("array before change 1",numa)
    nums1[0] = 100
    fmt.Println("array after modification to slice nums1", numa)
    nums2[1] = 101
    fmt.Println("array after modification to slice nums2", numa)
}

运行结果:

array before change 1 [78 79 80]  
array after modification to slice nums1 [100 79 80]  
array after modification to slice nums2 [100 101 80]

相关文章

  • Golang:切片的底层详解和初步使用

    什么是切片 切片是 Golang 中比较特殊的数据结构,这种数据结构更便于使用和管理数据集合。简单的说,切片就是一...

  • Golang之数组和切片

    引用 数组、字符串和切片 Go数组中的索引问题 深入解析 Go 中 Slice 底层实现 Golang 入门 : ...

  • EventBus

    《EventBus使用详解(一)——初步使用EventBus》 《EventBus使用详解(二)——EventBu...

  • golang:slice切片

    golang中的切片的索引是左闭右开的,切片不存储数据,它是对数组的引用,其他切片可以跟它共享同一个底层的数组,所...

  • golang - slice

    切片定义 切片是基于数组实现的,它的底层是数组,可以理解为对 底层数组的抽象。切片底层结构并没有使用加锁等方式,不...

  • Golang学习心得—切片

    在Golang中有数组和切片两种处理同类型数据序列的方式,但是我们大部分时间都在使用切片,Go的切片是在数组之上的...

  • Golang 入门 : 切片(slice)

    切片(slice)是 Golang 中一种比较特殊的数据结构,这种数据结构更便于使用和管理数据集合。切片是围绕动态...

  • Golang 入门 : 切片(slice)

    切片(slice)是 Golang 中一种比较特殊的数据结构,这种数据结构更便于使用和管理数据集合。切片是围绕动态...

  • go interface{}强制类型转化为其他类型

    我想对golang封装一个切片过滤的方法 filter 使用方法是传入任意类型的切片[]interface{},传...

  • Go切片:二级跳实现优雅的“数组”

    切片是一种数据结构,便于使用和管理数据集合,切片是基于数组的概念构成,可以按需自动增长和缩小,切片底层也会是在连续...

网友评论

      本文标题:Golang:切片的底层详解和初步使用

      本文链接:https://www.haomeiwen.com/subject/vckxuktx.html