yyz notes yyz notes
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

益章

可乐鸡翅
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • golang基础

    • 初识golang

    • golang基础语法

      • 变量
      • 常量
      • 基本数据类型
      • 复杂数据类型-指针
      • 复杂数据类型-数组array
      • 复杂数据类型-切片slice
        • 1. 切片的引入
        • 2. 内存分析
        • 3. 切片的定义
          • 1. 从数组或切片生成新的切片
          • 从指定范围中生成切片
          • 表示原有的切片
          • 重置切片,清空拥有的元素
          • 2. 直接声明新的切片
          • 3. 使用 make() 函数构造切片
          • 注意点
          • 代码示例
        • 4. 切片的增删改查
          • 增
          • 删
          • 改
          • 查
          • 遍历
          • 代码示例
        • 5. copy() 切片复制(切片拷贝)
          • 介绍
        • 6. 多维切片
        • 7. 切片注意点
          • 1. 切片定义后不可以直接使用,需要让其引用到一个数组,或者make一个空间供切片来使用
          • 2. 切片使用不能越界
          • 3. 切片可以继续切片
          • 4. 简写方式
          • 5. 切片可以动态增长
          • 6. 切片的拷贝
      • 复杂数据类型-映射map
      • 复杂数据类型-列表list
      • nil空值-零值
      • 关键字与标识符
      • 运算符
      • 输入输出
    • golang流程控制

    • golang函数

    • golang内置函数

    • golang包

    • golang错误异常处理

    • golang面向对象(结构体)

    • golang文件处理

    • golang并发编程简介

    • golang并发编程-协程

    • golang网络编程

    • 反射 reflect

  • golang高级

  • 常用组件

  • gin

  • golang
  • golang基础
  • golang基础语法
YiZhang-You
2023-05-21
目录

复杂数据类型-切片slice

# 1. 切片的引入

切片(slice)是对数组的一个连续片段的引用,所以切片是一个引用类型(因此更类似于 C/C++ (opens new window)

中的数组类型,或者Python (opens new window)中的 list 类型),这个片段可以是整个数组,也可以是由起始和终止索引标识的一些项的子集,需要注意的是,终止索引标识的项不包括在切片内。

Go语言中切片的内部结构包含地址、大小和容量,切片一般用于快速地操作一块数据集合

切片默认指向一段连续内存区域,可以是数组,也可以是切片本身。

从连续内存区域生成切片是常见的操作,格式如下:

slice [开始位置 : 结束位置]
1

语法说明如下:

  • slice:表示目标切片对象;
  • 开始位置:对应目标切片对象的索引;
  • 结束位置:对应目标切片的结束索引。

slice由三个部分构成,指针、长度、容量

指针:指针指向slice第一个元素对应的数组元素的地址。

长度:slice元素的数量,不得超过容量。

容器:slice开始的位置到底层数据的结尾。

package main

import "fmt"

func main() {
	var arr [6]int = [6]int{6, 5, 4, 3, 2, 1}
	fmt.Println("原数组", arr)

	// 切片构建在数组之上
	intArr := arr[2:6] // 前包后不包
	fmt.Println("输出切片", intArr)
	fmt.Println("输出切片个数", len(intArr))
	fmt.Println("输出切片容量(容量可以动态变化)", cap(intArr))
}
/*
	原数组 [6 5 4 3 2 1]
	输出切片 [4 3 2 1]
	输出切片个数 4
	输出切片容量(容量可以动态变化) 4
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 2. 内存分析

slice由三个部分构成,指针、长度、容量

  • 指针:指针指向slice第一个元素对应的数组元素的地址。
  • 长度:slice元素的数量,不得超过容量。
  • 容器:slice开始的位置到底层数据的结尾。

切片有3个字段的数据结构:一个是指向底层数组的指针,一个是切片的长度,一个是切片的容量。

切片本质还是保存的原数组的地址,所以修改了切片的内容数组的值也会被修改,相反修改了数组的内容切片也会被修改(切片在扩容时,容量的扩展规律是按容量的 2 倍数进行扩充)

package main

import "fmt"

func main() {
	var arr [5]int = [5]int{3, 6, 1, 4, 7}
	fmt.Println("原数组", arr)

	// 切片构建在数组之上
	intArr := arr[1:4] // 前包后不包
	fmt.Println("输出切片", intArr)
	fmt.Println("输出切片个数", len(intArr))
	fmt.Println("输出切片容量(容量可以动态变化)", cap(intArr))
	fmt.Println("数组下标为1的地址", &arr[1])
	fmt.Println("切片下标为1的地址", &intArr[1]) // 切片本质还是保存的原数组的地址,所以修改了切片的内容数组的值也会被修改
	intArr[1] = 16
	arr[1] = 99
	fmt.Println(arr)
	fmt.Println(intArr)
}
/*
	原数组 [3 6 1 4 7]
	输出切片 [6 1 4]
	输出切片个数 3
	输出切片容量(容量可以动态变化) 4
	数组下标为1的地址 0xc00000c368
	切片下标为1的地址 0xc00000c370
	[3 99 16 4 7]
	[99 16 4]
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 3. 切片的定义

# 1. 从数组或切片生成新的切片

切片默认指向一段连续内存区域,可以是数组,也可以是切片本身。

从连续内存区域生成切片是常见的操作,格式如下:

slice [开始位置 : 结束位置]
1

语法说明如下:

  • slice:表示目标切片对象;
  • 开始位置:对应目标切片对象的索引;
  • 结束位置:对应目标切片的结束索引。

从数组或切片生成新的切片拥有如下特性:

  • 取出的元素数量为:结束位置 - 开始位置;
  • 取出元素不包含结束位置对应的索引,切片最后一个元素使用 slice[len(slice)] 获取;
  • 当缺省开始位置时,表示从连续区域开头到结束位置;
  • 当缺省结束位置时,表示从开始位置到整个连续区域末尾;
  • 两者同时缺省时,与切片本身等效;
  • 两者同时为 0 时,等效于空切片,一般用于切片复位。

根据索引位置取切片 slice 元素值时,取值范围是(0~len(slice)-1),超界会报运行时错误,生成切片时,结束位置可以填写 len(slice) 但不会报错。

# 从指定范围中生成切片

var highRiseBuilding [30]int
for i := 0; i < 30; i++ {
        highRiseBuilding[i] = i + 1
}
// 区间
fmt.Println(highRiseBuilding[10:15])
// 中间到尾部的所有元素
fmt.Println(highRiseBuilding[20:])
// 开头到中间指定位置的所有元素
fmt.Println(highRiseBuilding[:2])

[11 12 13 14 15]
[21 22 23 24 25 26 27 28 29 30]
[1 2]
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 表示原有的切片

a := []int{1, 2, 3}
fmt.Println(a[:])

[1 2 3]
a 是一个拥有 3 个元素的切片,将 a 切片使用 a[:] 进行操作后,得到的切片与 a 切片一致,代码输出如下:
1
2
3
4
5

# 重置切片,清空拥有的元素

把切片的开始和结束位置都设为 0 时,生成的切片将变空,代码如下

a := []int{1, 2, 3}
fmt.Println(a[0:0])

[]
1
2
3
4

# 2. 直接声明新的切片

除了可以从原有的数组或者切片中生成切片外,也可以声明一个新的切片,每一种类型都可以拥有其切片类型,表示多个相同类型元素的连续集合,因此切片类型也可以被声明

var name []Type
1

其中 name 表示切片的变量名,Type 表示切片对应的元素类型。

// 声明字符串切片
var strList []string
// 声明整型切片
var numList []int
// 声明一个空切片
var numListEmpty = []int{}
// 输出3个切片
fmt.Println(strList, numList, numListEmpty)
// 输出3个切片大小
fmt.Println(len(strList), len(numList), len(numListEmpty))
// 切片判定空的结果
fmt.Println(strList == nil)
fmt.Println(numList == nil)
fmt.Println(numListEmpty == nil)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 3. 使用 make() 函数构造切片

如果需要动态地创建一个切片,可以使用 make() 内建函数

make( []Type, size, cap )

Type 是指切片的元素类型,size 指的是为这个类型分配多少个元素,cap 为预分配的元素数量,这个值设定后不影响 size,只是能提前分配空间,降低多次分配空间造成的性能问题

a := make([]int, 2)
b := make([]int, 2, 10)
fmt.Println(a, b)
fmt.Println(len(a), len(b))

[0 0] [0 0]
2 2
1
2
3
4
5
6
7

其中 a 和 b 均是预分配 2 个元素的切片,只是 b 的内部存储空间已经分配了 10 个,但实际使用了 2 个元素。

容量不会影响当前的元素个数,因此 a 和 b 取 len 都是 2。

# 注意点

使用 make() 函数生成的切片一定发生了内存分配操作,但给定开始与结束位置(包括切片复位)的切片只是将新的切片结构指向已经分配好的内存区域,设定开始与结束位置,不会发生内存分配操作。

# 代码示例

package main

import "fmt"

func main() {
	// 定义数组
	var arrAry [30]int
	for i := 0; i < 30; i++ {
		arrAry[i] = i + 1
	}

	// 一、从数组或切片生成新的切片
	// 1. 从指定范围中生成切片
	// 区间
	fmt.Println(arrAry[10:15])
	// 中间到尾部的所有元素
	fmt.Println(arrAry[20:])
	// 开头到中间指定位置的所有元素
	fmt.Println(arrAry[:2])

	// 2. 表示原有的切片
	fmt.Println(arrAry[:])

	// 3. 重置切片,清空拥有的元素
	fmt.Println(arrAry[0:0])

	// 二、直接声明新的切片
	// 声明字符串切片
	var strList []string
	// 声明整型切片
	var numList []int
	// 声明一个空切片
	var numListEmpty = []int{}
	// 输出3个切片
	fmt.Println(strList, numList, numListEmpty)
	// 输出3个切片大小
	fmt.Println(len(strList), len(numList), len(numListEmpty))
	// 切片判定空的结果
	fmt.Println(strList == nil)
	fmt.Println(numList == nil)
	fmt.Println(numListEmpty == nil)

	// 三、使用 make() 函数构造切片	make( []Type, size, cap )
	// Type 是指切片的元素类型,size 指的是为这个类型分配多少个元素,cap 为预分配的元素数量,这个值设定后不影响 size,只是能提前分配空间,降低多次分配空间造成的性能问题**
	a := make([]int, 2)
	b := make([]int, 2, 10)
	fmt.Println(a, b)
	fmt.Println(len(a), len(b))
	// 其中 a 和 b 均是预分配 2 个元素的切片,只是 b 的内部存储空间已经分配了 10 个,但实际使用了 2 个元素
}
/*
	[11 12 13 14 15]
	[21 22 23 24 25 26 27 28 29 30]
	[1 2]
	[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30]
	[]
	[] [] []
	0 0 0
	true
	true
	false
	[0 0] [0 0]
	2 2
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

# 4. 切片的增删改查

Go语言append()为切片添加元素 (opens new window)

# 增

函数 append() 可以为切片动态添加元素,在使用 append() 函数为切片动态添加元素时,如果空间不足以容纳足够多的元素,切片就会进行“扩容”,此时新切片的长度会发生改变。切片在扩容时,容量的扩展规律是按容量的 2 倍数进行扩充

package main

import "fmt"

func main() {
	// 定义切片
	var slice = make([]int, 5, 10)
	fmt.Println("原切片", slice)

	// 增
	slice = append(slice, 1) // 追加1个元素
	fmt.Println(slice)
	slice = append(slice, 1, 2, 3) // 追加多个元素, 手写解包方式
	fmt.Println(slice)
	slice = append(slice, []int{1, 2, 3}...) // 追加一个切片, 切片需要解包
	fmt.Println(slice)
	slice = append([]int{9}, slice...) // 在开头添加1个元素
	fmt.Println(slice)
	slice = append([]int{-3, -2, -1}, slice...) // 在开头添加1个切片
	fmt.Println(slice)
	slice = append(slice[:2], append([]int{99}, slice[1:]...)...) // 在第i个位置插入x 切片也支持链式操作
	fmt.Println(slice)
	slice = append(slice[:2], append([]int{99, 88, 77}, slice[1:]...)...) // 在第i个位置插入切片
	fmt.Println(slice)
}

/*
	原切片 [0 0 0 0 0]
	[0 0 0 0 0 1]
	[0 0 0 0 0 1 1 2 3]
	[0 0 0 0 0 1 1 2 3 1 2 3]
	[9 0 0 0 0 0 1 1 2 3 1 2 3]
	[-3 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[-3 -2 99 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[-3 -2 99 88 77 -2 99 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# 删

Go语言并没有对删除切片元素提供专用的语法或者接口,需要使用切片本身的特性来删除元素,根据要删除元素的位置有三种情况,分别是从开头位置删除、从中间位置删除和从尾部删除,其中删除切片尾部的元素速度最快。

Go语言中删除切片元素的本质是,以被删除元素为分界点,将前后两个部分的内存重新连接起来。

)

package main

import "fmt"

func main() {
	// 定义切片
	var slice = [...]int{-3 -2 99 88 77 -2 99 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3}

	fmt.Println("--------------------------------")
	// 删
	// 删除开头元素
	// 删除开头的元素可以直接移动数据指针
	slice = slice[1:] // 删除开头1个元素:
	fmt.Println(slice)
	// 删除开头1个元素:也可以不移动数据指针,但是将后面的数据向开头移动,可以用 append 原地完成(所谓原地完成是指在原有的切片数据对应的内存区间内完成,不会导致内存空间结构的变化)
	slice = append(slice[:0], slice[1:]...)
	fmt.Println(slice)
	// 用 copy() 函数来删除开头的元素
	slice = slice[:copy(slice, slice[1:])] // 删除开头1个元素
	fmt.Println(slice)

	// 删除中间元素
	// 对于删除中间的元素,需要对剩余的元素进行一次整体挪动,同样可以用 append 或 copy 原地完成
	slice = append(slice[:2], slice[4:]...) // 删除下标2到3的元素  slice = append(slice[:i], slice[i+N:]...) // 删除中间N个元素
	fmt.Println(slice)
	slice = slice[:2+copy(slice[2:], slice[3:])] // 删除中间1个元素  slice = slice[:i+copy(slice[i:], slice[i+N:])] // 删除中间N个元素
	fmt.Println(slice)

	// 从尾部删除
	slice = slice[:len(slice)-1] // 删除尾部1个元素
	//slice = slice[:len(slice)-N] // 删除尾部N个元素
	fmt.Println(slice)

}
/*
	[-3 -2 99 88 77 -2 99 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	--------------------------------
	[-2 99 88 77 -2 99 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[99 88 77 -2 99 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[88 77 -2 99 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[88 77 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[88 77 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[88 77 -1 9 0 0 0 0 0 1 1 2 3 1 2]
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

# 改

slice[0] = 9999
fmt.Println(slice)

[88 77 -1 9 0 0 0 0 0 1 1 2 3 1 2]
[9999 77 -1 9 0 0 0 0 0 1 1 2 3 1 2]
1
2
3
4
5

# 查

# 遍历

//方式1:普通for循环
	for i := 0; i < len(slice); i++ {
		fmt.Printf("slice[%v] = %v \\t", i, slice[i])
	}
	fmt.Println("\\n------------------------------")
	//方式2:for-range循环:
	for i, v := range slice {
		fmt.Printf("下标:%v ,元素:%v\\n", i, v)
	}
1
2
3
4
5
6
7
8
9

# 代码示例

package main

import "fmt"

func main() {
	// 定义切片
	var slice = make([]int, 5, 10)
	fmt.Println("原切片", slice)

	// 增
	slice = append(slice, 1) // 追加1个元素
	fmt.Println(slice)
	slice = append(slice, 1, 2, 3) // 追加多个元素, 手写解包方式
	fmt.Println(slice)
	slice = append(slice, []int{1, 2, 3}...) // 追加一个切片, 切片需要解包
	fmt.Println(slice)
	slice = append([]int{9}, slice...) // 在开头添加1个元素
	fmt.Println(slice)
	slice = append([]int{-3, -2, -1}, slice...) // 在开头添加1个切片
	fmt.Println(slice)
	slice = append(slice[:2], append([]int{99}, slice[1:]...)...) // 在第i个位置插入x 切片也支持链式操作
	fmt.Println(slice)
	slice = append(slice[:2], append([]int{99, 88, 77}, slice[1:]...)...) // 在第i个位置插入切片
	fmt.Println(slice)

	fmt.Println("--------------------------------")
	// 删
	// 删除开头元素
	// 删除开头的元素可以直接移动数据指针
	slice = slice[1:] // 删除开头1个元素:
	fmt.Println(slice)
	// 删除开头1个元素:也可以不移动数据指针,但是将后面的数据向开头移动,可以用 append 原地完成(所谓原地完成是指在原有的切片数据对应的内存区间内完成,不会导致内存空间结构的变化)
	slice = append(slice[:0], slice[1:]...)
	fmt.Println(slice)
	// 用 copy() 函数来删除开头的元素
	slice = slice[:copy(slice, slice[1:])] // 删除开头1个元素
	fmt.Println(slice)

	// 删除中间元素
	// 对于删除中间的元素,需要对剩余的元素进行一次整体挪动,同样可以用 append 或 copy 原地完成
	slice = append(slice[:2], slice[4:]...) // 删除下标2到3的元素  slice = append(slice[:i], slice[i+N:]...) // 删除中间N个元素
	fmt.Println(slice)
	slice = slice[:2+copy(slice[2:], slice[3:])] // 删除中间1个元素  slice = slice[:i+copy(slice[i:], slice[i+N:])] // 删除中间N个元素
	fmt.Println(slice)

	// 从尾部删除
	slice = slice[:len(slice)-1] // 删除尾部1个元素
	//slice = slice[:len(slice)-N] // 删除尾部N个元素
	fmt.Println(slice)

	// 改
	slice[0] = 9999
	fmt.Println(slice)

	// 查
	//方式1:普通for循环
	for i := 0; i < len(slice); i++ {
		fmt.Printf("slice[%v] = %v \t", i, slice[i])
	}
	fmt.Println("\n------------------------------")
	//方式2:for-range循环:
	for i, v := range slice {
		fmt.Printf("下标:%v ,元素:%v\n", i, v)
	}

}

/*
	原切片 [0 0 0 0 0]
	[0 0 0 0 0 1]
	[0 0 0 0 0 1 1 2 3]
	[0 0 0 0 0 1 1 2 3 1 2 3]
	[9 0 0 0 0 0 1 1 2 3 1 2 3]
	[-3 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[-3 -2 99 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[-3 -2 99 88 77 -2 99 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	--------------------------------
	[-2 99 88 77 -2 99 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[99 88 77 -2 99 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[88 77 -2 99 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[88 77 -2 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[88 77 -1 9 0 0 0 0 0 1 1 2 3 1 2 3]
	[88 77 -1 9 0 0 0 0 0 1 1 2 3 1 2]
	[9999 77 -1 9 0 0 0 0 0 1 1 2 3 1 2]
	slice[0] = 9999         slice[1] = 77   slice[2] = -1   slice[3] = 9    slice[4] = 0    slice[5] = 0    slice[6] = 0    slice[7] = 0    slice[8] = 0    slice[9] = 1    slice[10] = 1   slice[11] = 2  slice[12] = 3   slice[13] = 1   slice[14] = 2
	------------------------------
	下标:0 ,元素:9999
	下标:1 ,元素:77
	下标:2 ,元素:-1
	下标:3 ,元素:9
	下标:4 ,元素:0
	下标:5 ,元素:0
	下标:6 ,元素:0
	下标:7 ,元素:0
	下标:8 ,元素:0
	下标:9 ,元素:1
	下标:10 ,元素:1
	下标:11 ,元素:2
	下标:12 ,元素:3
	下标:13 ,元素:1
	下标:14 ,元素:2
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

# 5. copy() 切片复制(切片拷贝)

Go语言copy():切片复制(切片拷贝) (opens new window)

# 介绍

Go语言的内置函数 copy() 可以将一个数组切片复制到另一个数组切片中,如果加入的两个数组切片不一样大,就会按照其中较小的那个数组切片的元素个数进行复制。

copy() 函数的使用格式如下:

copy( destSlice, srcSlice []T) int
1

其中 srcSlice 为数据来源切片,destSlice 为复制的目标(也就是将 srcSlice 复制到 destSlice),目标切片必须分配过空间且足够承载复制的元素个数,并且来源和目标的类型必须一致,copy() 函数的返回值表示实际发生复制的元素个数。

package main

import "fmt"

func main() {
	slice1 := []int{1, 2, 3, 4, 5}
	slice2 := []int{51, 41, 31}
	copy(slice2, slice1) // 只会复制slice1的前3个元素到slice2中
	fmt.Println(slice1, slice2)

	slice3 := []int{1, 2, 3, 4, 5}
	slice4 := []int{51, 41, 31}
	copy(slice3, slice4) // 只会复制slice4的3个元素到slice3的前3个位置
	fmt.Println(slice3, slice4)
}
/*
	[1 2 3 4 5] [1 2 3]
	[51 41 31 4 5] [51 41 31]
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 6. 多维切片

Go语言多维切片简述 (opens new window)

# 7. 切片注意点

# 1. 切片定义后不可以直接使用,需要让其引用到一个数组,或者make一个空间供切片来使用

# 2. 切片使用不能越界

# 3. 切片可以继续切片

# 4. 简写方式

# 5. 切片可以动态增长

package main
import "fmt"
func main(){
        //定义数组:
        var intarr [6]int = [6]int{1,4,7,3,6,9}
        //定义切片:
        var slice []int = intarr[1:4] //4,7,3
        fmt.Println(len(slice))
        slice2 := append(slice,88,50)
        fmt.Println(slice2) //[4 7 3 88 50]
        fmt.Println(slice)
        //底层原理:
        //1.底层追加元素的时候对数组进行扩容,老数组扩容为新数组:
        //2.创建一个新数组,将老数组中的4,7,3复制到新数组中,在新数组中追加88,50
        //3.slice2 底层数组的指向 指向的是新数组 
        //4.往往我们在使用追加的时候其实想要做的效果给slice追加:
        slice = append(slice,88,50)
        fmt.Println(slice)
        //5.底层的新数组 不能直接维护,需要通过切片间接维护操作。
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 6. 切片的拷贝

编辑 (opens new window)
复杂数据类型-数组array
复杂数据类型-映射map

← 复杂数据类型-数组array 复杂数据类型-映射map→

最近更新
01
配置yun源
05-24
02
linux-配置python虚拟环境
05-24
03
linux文件目录管理
05-24
更多文章>
Theme by Vdoing | Copyright © 2023-2023 yizhang | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式