【Go实战基础】slice 切片为什么更常用

打印 上一主题 下一主题

主题 940|帖子 940|积分 2820

数组元素固定,在 Go 语言中没有那么常用,更常用的数据结构是切片。

什么是切片呢? 切片就是动态的数组,它的长度不固定,可以随意向切片中追加元素,而且切片会在容量不足的时候自动扩容。

切片(slice)是对数组一个连续片段的引用,这个片段可以是整个数组,或者是由起始和终止索引标识的一些项的子集,需要注意的是,终止索引标识的项不包括在切片内,切片提供了一个与指向数组的动态窗口。

切片的数据结构如下:
  1.     type slice struct {
  2.         // Pointer 是指向一个数组的指针
  3.         array unsafe.Pointer
  4.      
  5.         // 当前切片的长度
  6.         len   int
  7.      
  8.         // cap 是当前切片的容量。cap 总是大于等于 len 的。
  9.         cap   int
  10.     }
复制代码
 
Pointer 作为一个指针指向的数组是一片连续的内存空间,这片内存空间可以用于存储切片中保存的全部元素,底层存储都是连续的,所以可以将切片理解为一片连续的内存空间加上长度与容量的标识。

  1.     实战需求: slice 切片的实现原理
复制代码
马上安排!

一、工程目录
  1.     cd go-003/
复制代码
二、创建 g003.go
  1.     /*
  2.      * @Author: 菜鸟实战
  3.      * @FilePath: /go110/go-003/g003.go
  4.      * @Description: slice 切片
  5.      */
  6.      
  7.     package main
  8.      
  9.     import (
  10.         "fmt"
  11.         "runtime"
  12.     )
  13.      
  14.     // 主函数
  15.     func main() {
  16.         // 使用内置函数打印
  17.         println("Hello", "菜鸟实战")
  18.      
  19.         //定义一个无初始长度的切片
  20.         s := []string{}
  21.      
  22.         for i := 0; i < 6; i++ {
  23.      
  24.             // 拼接元素
  25.             s = append(s, "eeeee")
  26.      
  27.             // 拼接后会动态扩容
  28.             fmt.Printf("容量: %v, 长度 : %v \n", cap(s), len(s))
  29.         }
  30.      
  31.         // 使用包函数打印
  32.         fmt.Printf("版本: %s \n", runtime.Version())
  33.     }
复制代码
 
三、编译和运行

    # 1、生成模块依赖
  1.     go mod init g003
复制代码
    # 2、编译
  1.     go build g003.go
  2.  
复制代码
    # 3、编译后的目录结构
  1.      
  2.     └── go-003
  3.         ├── g003
  4.         ├── g003.go
  5.         └── go.mod
  6.      
复制代码
    # 4、运行
  1.     go run g003
复制代码
四、运行结果
    Hello 菜鸟实战
    容量: 1, 长度 : 1
    容量: 2, 长度 : 2
    容量: 4, 长度 : 3
    容量: 4, 长度 : 4
    容量: 8, 长度 : 5
    容量: 8, 长度 : 6
    版本: go1.17.10

由输出结果可以看到,Slice 的容量会自动扩容的起点是 2,当长度大于 2 时,slice 的容量会自动扩容为原来的 2 倍,每一次扩容都会重新开辟一块内存空间,将旧的数据复制到新开辟的内存空间中,然后释放旧的内存空间。

数组长度是固定的,而 Go 中使用的切片设计想法是由动态数组概念而来,可以用来管理数据集合,并可以自动增加和减少,但是切片本身并不是动态数据或者数组指针,与此同时,切片还具有可索引,可迭代的优秀特性,因此使用也更为广范。

菜鸟实战,持续学习!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

去皮卡多

金牌会员
这个人很懒什么都没写!

标签云

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