当前位置: 首页 > article >正文

Golang学习笔记_14——切片

Golang学习笔记_11——指针
Golang学习笔记_12——结构体
Golang学习笔记_13——数组


文章目录

    • 切片
      • 1. 定义
      • 2. 创建
      • 3. 基本操作
      • 4. 动态性
      • 5. 子切片
      • 6. 数组和切片
      • 7. 注意
      • 8. 高级用法
    • 源码


切片

Go语言中的切片(slice)是一种非常强大且灵活的数据结构,它基于数组,但提供了更加动态和方便的接口。

1. 定义

切片是对数组的抽象和封装,它包含三个关键部分:

  1. 指向数组的指针:切片存储了数组的首地址,指向数组中的某个元素。
  2. 切片的长度(len):切片中元素的数量。
  3. 切片的容量(cap):从切片的首元素到数组末尾的元素数量,表示在不需要重新分配底层数组的情况下,切片可以增长的最大长度。

2. 创建

func sliceDemo1() {
	// 通过字面量创建
	s1 := []int{1, 2, 3}

	// 通过make函数创建
	// 创建一个长度为3,容量为5的切片
	s2 := make([]int, 3, 5)

	// 基于数组创建
	arr := [5]int{1, 2, 3, 4, 5}
	s3 := arr[1:4]

	fmt.Println(s1, s2, s3)

}

3. 基本操作

func sliceDemo2() {
	// 访问和修改元素
	s1 := []int{1, 2, 3}
	fmt.Println(s1[0]) // 输出1
	s1[0] = 10

	fmt.Println(s1)

	// 切片多重赋值
	a, b, c := s1[0], s1[1], s1[2]
	fmt.Println(a, b, c)

	// 切片的长度和容量
	s := []int{1, 2, 3, 4, 5}
	fmt.Println(len(s)) // 输出5
	fmt.Println(cap(s)) // 输出5,因为是基于字面量创建的,默认容量等于长度

}

测试方法

func Test_sliceDemo2(t *testing.T) {
	sliceDemo2()
}

输出结果

=== RUN   Test_sliceDemo2
1
[10 2 3]
10 2 3
5
5
--- PASS: Test_sliceDemo2 (0.00s)
PASS

4. 动态性

func sliceDemo3() {
	s := []int{1, 2, 3}
	s = append(s, 4, 5) // s现在是[1, 2, 3, 4, 5]
	fmt.Println(s)
}

测试方法

func Test_sliceDemo3(t *testing.T) {
	sliceDemo3()
}

输出结果

=== RUN   Test_sliceDemo3
[1 2 3 4 5]
--- PASS: Test_sliceDemo3 (0.00s)
PASS

当向切片中追加元素时,如果切片的容量不足,Go会自动分配一个更大的底层数组,并将原有元素复制到新的数组中。新数组的容量通常是原容量的两倍。

5. 子切片

func sliceDemo4() {
	s := []int{1, 2, 3, 4, 5}
	subSlice := s[1:4] // subSlice是[2, 3, 4]
	fmt.Println(subSlice)
}

测试方法

func Test_sliceDemo4(t *testing.T) {
	sliceDemo4()
}

输出结果

=== RUN   Test_sliceDemo4
[2 3 4]
--- PASS: Test_sliceDemo4 (0.00s)
PASS

6. 数组和切片

  1. 长度:数组的长度是固定的,而切片的长度是动态的。
  2. 内存分配:数组直接存储数据,切片是对数组的抽象,存储的是指向数组的指针、长度和容量。
  3. 效率:数组在栈上分配内存,效率较高,但长度固定;切片在堆上分配内存,且可以动态扩展,但有一定性能开销。

7. 注意

  1. 共享底层数组:多个切片可以共享同一个底层数组,修改一个切片可能影响其他切片。

  2. 越界访问:访问切片时,如果索引超出范围,会导致运行时错误(panic)。

  3. nil切片:未初始化的切片值为nil,长度为0,容量为0。

  4. 在进行切片时,你可以利用它的默认行为来忽略上下界。切片下界的默认值为 0,上界则是该切片的长度。

    var a [10]int
    
    a[0:10]
    a[:10]
    a[0:]
    a[:]
    // 上述表达是等价的
    

8. 高级用法

func sliceDemo5() {
	// 切片拷贝
	s := []int{1, 2, 3}
	var s_dst = make([]int, len(s))
	copy(s, s_dst)
	fmt.Println(s_dst)

	// 切片分割
	s1 := []int{1, 2, 3}
	s2 := []int{4, 5, 6}
	s3 := append(s1, s2...) // s3是[1, 2, 3, 4, 5, 6]
	fmt.Println(s3)
}

测试方法

func Test_sliceDemo5(t *testing.T) {
	sliceDemo5()
}

输出结果

=== RUN   Test_sliceDemo5
[0 0 0]
[1 2 3 4 5 6]
--- PASS: Test_sliceDemo5 (0.00s)
PASS

源码

// slice_demo.go 文件
package _4_slice_demo

import "fmt"

func sliceDemo1() {
	// 通过字面量创建
	s1 := []int{1, 2, 3}

	// 通过make函数创建
	// 创建一个长度为3,容量为5的切片
	s2 := make([]int, 3, 5)

	// 基于数组创建
	arr := [5]int{1, 2, 3, 4, 5}
	s3 := arr[1:4]

	fmt.Println(s1, s2, s3)

}

func sliceDemo2() {
	// 访问和修改元素
	s1 := []int{1, 2, 3}
	fmt.Println(s1[0]) // 输出1
	s1[0] = 10

	fmt.Println(s1)

	// 切片多重赋值
	a, b, c := s1[0], s1[1], s1[2]
	fmt.Println(a, b, c)

	// 切片的长度和容量
	s := []int{1, 2, 3, 4, 5}
	fmt.Println(len(s)) // 输出5
	fmt.Println(cap(s)) // 输出5,因为是基于字面量创建的,默认容量等于长度

}

func sliceDemo3() {
	s := []int{1, 2, 3}
	s = append(s, 4, 5) // s现在是[1, 2, 3, 4, 5]
	fmt.Println(s)
}

func sliceDemo4() {
	s := []int{1, 2, 3, 4, 5}
	subSlice := s[1:4] // subSlice是[2, 3, 4]
	fmt.Println(subSlice)
}

func sliceDemo5() {
	// 切片拷贝
	s := []int{1, 2, 3}
	var s_dst = make([]int, len(s))
	copy(s, s_dst)
	fmt.Println(s_dst)

	// 切片分割
	s1 := []int{1, 2, 3}
	s2 := []int{4, 5, 6}
	s3 := append(s1, s2...) // s3是[1, 2, 3, 4, 5, 6]
	fmt.Println(s3)
}
// 14_slice_demo_test.go 文件
package _4_slice_demo

import "testing"

func Test_sliceDemo2(t *testing.T) {
	sliceDemo2()
}

func Test_sliceDemo3(t *testing.T) {
	sliceDemo3()
}

func Test_sliceDemo4(t *testing.T) {
	sliceDemo4()
}

func Test_sliceDemo5(t *testing.T) {
	sliceDemo5()
}

http://www.kler.cn/a/443439.html

相关文章:

  • 监听器与RBAC权限模型
  • Java语言的语法
  • 【Qt】QtConcurrent
  • 【第01阶段-基础必备篇-第二部分--Python之基础】04 函数
  • 【Unity3D】Text文本文字掉落效果
  • 【Linux系列】并发与顺序执行:在 Linux 脚本中的应用与选择
  • Docker 镜像加速和配置的分享 云服务器搭建beef-xss
  • Kubernetes中subPath
  • Android笔记【20】
  • 36.3 grafana-dashboard看图分析
  • 【C++】inline函数(内联函数)
  • 录音有杂音怎么消除?去杂音降噪音的方法
  • 自动驾驶AVM环视算法--python版本的540投影模式
  • C++ Learning explicit关键字•静态成员
  • 机器人阻抗和导纳控制的区别
  • Azure虚拟机非托管磁盘大小调整
  • 三相异步电动机噪音大有哪些原因?
  • Java线程池解读
  • 东方博宜24年12月-B组(才俊)- 重铠马的选择
  • 如何利用Python爬虫获得1688按关键字搜索商品
  • SSL Version 2 and 3 Protocol Detection漏洞修复
  • C#经典算法面试题
  • 【ORACLE】一个允许关键字作为别名所引起的语法歧义场景
  • Python轻量级NoSQL数据库TinyDB
  • 智能人家谱程序创意
  • 使用 Elasticsearch 查询和数据同步的实现方法