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
}
相关推荐
秋野酱2 分钟前
基于javaweb的SpringBoot足球俱乐部管理系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
KyollBM6 分钟前
数学——A. K-divisible Sum + D. Exam in MAC
c++·算法·macos
渔樵江渚上11 分钟前
深入理解 Web Worker
前端·javascript·面试
prettyxian11 分钟前
【c++】继承
开发语言·c++·算法
翱翔-蓝天15 分钟前
Spring Boot使用线程池创建多线程
java·spring boot·后端
旧厂街小江16 分钟前
LeetCode第76题:最小覆盖子串
后端·算法·程序员
uhakadotcom17 分钟前
ClickHouse与PostgreSQL:数据库的选择与应用场景
后端·面试·github
愚戏师18 分钟前
Python:函数式编程
开发语言·python·算法
闯闯的日常分享23 分钟前
浅析HTTP与HTTPS的区别
后端
四七伵24 分钟前
MySQL主键生成的4种方式:优缺点及性能对比!
后端·mysql