【Go】切片

知识点 关键概念
切片声明 var slice []int
初始化切片 slice := []int{1,2,3}
make() 创建切片 make([]int, len, cap)
获取长度和容量 len(slice), cap(slice)
追加元素 slice = append(slice, value)
切片截取 slice[start:end](返回子切片)
拷贝切片 copy(dest, src)(不会共享底层数组)
删除元素 slice = append(slice[:index], slice[index+1:]...)
nil 切片 vs 空切片 nilSlice == nil,len(emptySlice) == 0
切片扩容 超过 cap 后,自动扩容

1. 切片的基本概念

代码示例

go 复制代码
package main

import "fmt"

func main() {
	// 声明切片
	var slice1 []int
	fmt.Println(slice1) // []

	// 直接初始化切片
	slice2 := []int{1, 2, 3, 4, 5}
	fmt.Println(slice2) // [1 2 3 4 5]
}

学习笔记

  • 切片是一种动态数组,可以扩容,而数组长度固定。
  • 切片本质上是对底层数组的引用 ,它存储的是 指向底层数组的指针、长度和容量。
  • 切片可以通过 {} 直接初始化,不需要指定长度。

2. 使用 make() 创建切片

代码示例

go 复制代码
package main

import "fmt"

func main() {
	// 创建一个长度为 5 的切片,默认值为 0
	slice1 := make([]int, 5)
	fmt.Println(slice1) // [0 0 0 0 0]

	// 创建一个长度为 7,容量为 10 的切片
	slice2 := make([]int, 7, 10)
	fmt.Println(slice2)                  // [0 0 0 0 0 0 0]
	fmt.Println("长度:", len(slice2))    // 7
	fmt.Println("容量:", cap(slice2))    // 10
}

学习笔记

  • make([]type, len, cap) 用于创建切片 ,其中:
    • len 是切片的初始长度。
    • cap 是切片的容量(可选)。
  • len() 获取切片长度,cap() 获取切片容量。
  • 切片长度 <= 容量,超过容量时会自动扩展。

3. 切片的 append() 操作

代码示例

go 复制代码
package main

import "fmt"

func main() {
	slice := []string{"A", "B"}
	slice = append(slice, "C", "D") // 追加元素
	fmt.Println(slice)              // [A B C D]
}

学习笔记

  • append() 用于向切片追加元素 ,如果超出容量,Go 会 自动扩容 并分配新的底层数组。

4. 切片的截取

代码示例

go 复制代码
package main

import "fmt"

func main() {
	slice := []int{1, 2, 3, 4, 5, 6, 7}
	subSlice := slice[1:4] // 从索引 1 截取到索引 4(不包含 4)
	fmt.Println(subSlice)  // [2 3 4]

	subSlice[1] = 100 // 修改 subSlice 会影响原切片
	fmt.Println(slice) // [1 2 100 4 5 6 7]
}

学习笔记

  • slice[start:end] 获取 [start, end) 之间的元素 (不包含 end)。
  • 修改子切片的值会影响原切片,因为它们共用相同的底层数组。

5. 使用 copy() 进行切片拷贝

代码示例

go 复制代码
package main

import "fmt"

func main() {
	src := []int{1, 2, 3, 4, 5}
	dest := make([]int, len(src))

	copy(dest, src) // 复制 src 到 dest
	fmt.Println(dest) // [1 2 3 4 5]

	src[0] = 100
	fmt.Println(src)  // [100 2 3 4 5]
	fmt.Println(dest) // [1 2 3 4 5] (不受影响)
}

学习笔记

  • copy(dest, src) 用于复制切片,不会共享底层数组。
  • 修改 src 不会影响 dest,避免数据被误修改。

6. 切片的删除操作

代码示例

go 复制代码
package main

import "fmt"

func main() {
	slice := []int{1, 2, 3, 4, 5}
	slice = append(slice[:2], slice[3:]...) // 删除索引 2 的元素
	fmt.Println(slice) // [1 2 4 5]
}

学习笔记

  • Go 没有 remove() 方法 ,删除元素时需要使用 append() 将前后部分拼接。
  • slice[:index] + slice[index+1:] 实现删除 ,需要 ... 进行解包。

7. nil 切片 vs 空切片

代码示例

go 复制代码
package main

import "fmt"

func main() {
	var nilSlice []int
	emptySlice := []int{}

	if nilSlice == nil {
		fmt.Println("nilSlice 是 nil")
	}

	if len(emptySlice) == 0 {
		fmt.Println("emptySlice 是空切片")
	}
}

学习笔记

  • nil 切片是未分配内存的切片,值为 nil,常用于表示 "无数据"。
  • 空切片已经初始化,但 len() == 0 ,可以安全使用 append() 添加数据。

8. 切片扩容机制

代码示例

go 复制代码
package main

import "fmt"

func main() {
	slice := []int{}
	fmt.Println("初始容量:", cap(slice))

	for i := 1; i <= 10; i++ {
		slice = append(slice, i)
		fmt.Printf("追加 %d 后,长度: %d, 容量: %d\n", i, len(slice), cap(slice))
	}
}

学习笔记

  • 切片的容量按 2 倍增长 :
    • 当 len(slice) < cap(slice),append() 直接使用现有的底层数组。
    • 当超出 cap(slice),Go 会 重新分配内存 并扩展容量。

一、go1.18 之前:

1.如果期望容量大于当前容量的两倍就会使用期望容量;

2.如果当前切片的长度小于 1024 就会将容量翻倍;

3.如果当前切片的长度大于 1024 就会每次增加 25% 的容量,直到新容量大于期望容量;

二、go1.18 之后:

1.如果期望容量大于当前容量的两倍就会使用期望容量;

2.如果当前切片的长度小于阈值(默认 256)就会将容量翻倍;

3.如果当前切片的长度大于等于阈值(默认 256),就会每次增加 25% 的容量,基准是 newcap + 3*threshold,直到新容量大于期望容量;

扩容机制笔记参考自:https://blog.csdn.net/qq_47831505/article/details/135540661

相关推荐
m0_380743873 小时前
C++中的freopen的用法实例详解
开发语言·c++
Escalating_xu3 小时前
【Python】基础语法(1):常量、变量、类型、输入输出与运算符
开发语言·python
jimy14 小时前
polymorph.cpp里面的“析构函数、智能指针”问题
开发语言·c++
m0_380743874 小时前
PHP 8.3 缓存清除不生效怎么排查
开发语言·php
朝朝辞暮i4 小时前
C++ 第 6 课:switch —— 多状态选择
开发语言·c++·算法
小凡geo4 小时前
本地商家 GEO:用脚本一键生成 FAQPage 结构化数据,让 AI 切片更稳
开发语言·人工智能·python·microsoft·搜索引擎·ai
朝朝辞暮i5 小时前
C++ 第 4 课:if / else —— 让程序自己做决定
开发语言·c++
波力海苔夹心脆6755 小时前
C# 值类型与引用类型详解:存储位置、赋值机制、参数传递、相等比较、装箱拆箱与常见陷阱
开发语言·jvm·经验分享·笔记·c#·.net
蜗牛互联网5 小时前
WSL Containers GA:本地AI容器的生命周期、网络与治理验收
java·网络·人工智能·后端
m0_380743875 小时前
Qt中导航栏实现的详细指南
开发语言·c++