Go的Slice底层数据结构和特性

Go 的 Slice 底层数据结构和特性

Slice 是 Go 语言中一种动态数组的实现,它提供了比数组更灵活的操作方式。Slice 的底层数据结构是一个结构体,包含指向数组的指针、长度和容量。


1. 底层数据结构

Slice 的底层数据结构是一个包含三个字段的结构体:

  • array:指向底层数组的指针,存储实际的数据。
  • len:当前 Slice 的长度,表示实际存储的元素个数。
  • cap:当前 Slice 的容量,表示底层数组的总大小。

2. 特性

动态扩展
  • 自动扩容:当 Slice 的长度超过容量时,Go 会自动分配一个更大的底层数组,并将原有数据复制到新数组中。
  • 扩容策略:通常,新容量是原容量的两倍,但当容量较大时,扩容因子会减小。
引用类型
  • 共享底层数组:多个 Slice 可以共享同一个底层数组,修改一个 Slice 可能会影响其他 Slice。
  • 浅拷贝:Slice 的赋值和传递是浅拷贝,只复制指针、长度和容量,不复制底层数组。
切片操作
  • 切片表达式 :可以通过切片表达式 s[start:end] 创建一个新的 Slice,新 Slice 共享原 Slice 的底层数组。
  • 容量限制:新 Slice 的容量受原 Slice 的容量限制。

3. 使用场景

动态数组
  • 动态大小:适用于需要动态调整大小的数组场景。
  • 高效操作:支持高效的插入、删除和扩展操作。
数据共享
  • 共享数据:适用于需要共享底层数据的场景,如多个 Slice 共享同一个数组。
高效传递
  • 减少拷贝:由于 Slice 是引用类型,传递 Slice 时不会复制底层数组,适合传递大数据。

Slice 底层数组 长度 len 容量 cap 元素 1 元素 2 ... 元素 n

代码示例
go 复制代码
package main

import "fmt"

func main() {
    // 创建并初始化 Slice
    s := []int{1, 2, 3, 4, 5}
    fmt.Println("Initial Slice:", s) // 输出: Initial Slice: [1 2 3 4 5]
    fmt.Println("Initial Length:", len(s)) // 输出: Initial Length: 5
    fmt.Println("Initial Capacity:", cap(s)) // 输出: Initial Capacity: 5

    // 动态扩展 Slice
    s = append(s, 6, 7, 8)
    fmt.Println("Extended Slice:", s) // 输出: Extended Slice: [1 2 3 4 5 6 7 8]
    fmt.Println("Extended Length:", len(s)) // 输出: Extended Length: 8
    fmt.Println("Extended Capacity:", cap(s)) // 输出: Extended Capacity: 10

    // 共享底层数组
    s1 := s[2:5]
    fmt.Println("Slice s1:", s1) // 输出: Slice s1: [3 4 5]
    fmt.Println("Length of s1:", len(s1)) // 输出: Length of s1: 3
    fmt.Println("Capacity of s1:", cap(s1)) // 输出: Capacity of s1: 8

    // 修改 s1 会影响原 Slice s
    s1[0] = 99
    fmt.Println("Modified Slice s:", s) // 输出: Modified Slice s: [1 2 99 4 5 6 7 8]
    fmt.Println("Modified Slice s1:", s1) // 输出: Modified Slice s1: [99 4 5]

    // 切片操作
    s2 := s[:3]
    fmt.Println("Slice s2:", s2) // 输出: Slice s2: [1 2 99]
    fmt.Println("Length of s2:", len(s2)) // 输出: Length of s2: 3
    fmt.Println("Capacity of s2:", cap(s2)) // 输出: Capacity of s2: 10
}
相关推荐
oak隔壁找我3 小时前
MySQL中 SHOW FULL PROCESSLIST` 输出中 `State` 列的所有可能值
后端
上进小菜猪4 小时前
基于 YOLOv8 的面向文档智能处理的表格区域检测系统 [目标检测完整源码]
后端
oak隔壁找我4 小时前
JVM常用调优参数
java·后端
IT_陈寒8 小时前
React状态管理终极对决:Redux vs Context API谁更胜一筹?
前端·人工智能·后端
晨星shine9 小时前
GC、Dispose、Unmanaged Resource 和 Managed Resource
后端·c#
蝎子莱莱爱打怪9 小时前
OpenClaw 从零配置指南:接入飞书 + 常用命令 + 原理图解
java·后端·ai编程
倚栏听风雨9 小时前
【ES避坑指南】明明存的是 "CodingAddress",为什么 term 查询死活查不到?彻底搞懂 text 和 keyword
后端
程序员爱钓鱼9 小时前
Go 操作 Windows COM 自动化实战:深入解析 go-ole
后端·go·排序算法
回家路上绕了弯10 小时前
深入解析Agent Subagent架构:原理、协同逻辑与实战落地指南
分布式·后端
子玖10 小时前
实现微信扫码注册登录-基于参数二维码
后端·微信·go