01-go基础-06-切片(声明切片、初始化切片、切片赋值、切片长度、切片容量、空切片、append、copy)

news/2024/10/17 13:36:21/

文章目录

  • 1. 声明切片
  • 2. 初始化切片
    • 2.1 切片长度
      • 2.1.1 初始化指定长度的切片
      • 2.1.2 查看切片长度 len()
    • 2.2 切片容量
      • 2.2.1 初始化指定容量的切片
      • 2.2.2 查看切片长度 len()
  • 3 切片赋值
    • 3.1 直接赋值
    • 3.2 引用数组给切片赋值
    • 3.3 引用数组某区间给切片赋值
      • 3.3.1 从数组位置N个取到第M个元素,赋值给切片
        • - 语法
        • - 示例
      • 3.3.2 从数组位置N取到结尾,赋值给切片
        • - 语法
        • - 示例
      • 3.3.3 从开头取到第M个元素,赋值给切片
        • - 语法
        • - 示例
    • 3.4 通过切片赋值给切片
  • 4. 空切片
    • 4.1 仅声明的切片为空
    • 4.2 初始容量为0的切片不为空
  • 5. append()
    • - 语法
    • - 示例1(添加一个成员)
    • - 示例2(添加多个成员)
    • - 示例3(添加成员赋值给新切片)
  • 6. copy() 函数
    • - 语法
    • - 示例1(新切片长度 >= 原切片长度)
    • - 示例2 (新切片长度 < 原切片长度)
    • - 示例2 (新切未初始化)

数组和切片的区别
数组是需要指定个数的,而切片则不需要。

1. 声明切片

  • 语法
var  SliceName []type
  • 语法示例

定义一个切片,且切片成员为字符串类型

var names []string

2. 初始化切片

声明切片的同时,为切片分配一个内存地址。

2.1 切片长度

2.1.1 初始化指定长度的切片

说明:len表示数组长度,即切片的初始长度

  • 语法
var  slice1  = make([]type, len)

在函数内,可简写做:

slice1 := make([]type, len)
  • 语法示例
var names  = make([]string,3)

函数内可以写做:

names  := make([]string,3)

当然你也可以先声明,然后在初始化

var names []string
names  = make([]string,3)

2.1.2 查看切片长度 len()

  • 语法
len(SliceName)
  • 示例
package mainimport "fmt"func main() {names  := make([]string,10)fmt.Printf("切片:%+v\n长度为:%d",names,len(names))
}

结果打印

切片:[         ]
长度为:10
  • 说明:

问:明明打印的切片没有成员,为什么长度为10?
答:可以看见我们打印出的结果是[ ]而不是[]。这里边有9个空格,即是10个成员间的9个分隔符(空格)。我们看不到成员,是因为这10个成员的值默认都是空(字串不赋值默认为空)。如果我们定义切片成员类型是int我们将看到打印出10个0(int类型不赋值,默认为0)

package mainimport "fmt"func main() {slice1  := make([]int,10)fmt.Printf("切片:%+v\n长度为:%d",slice1,len(slice1))
}

结果:

切片:[0 0 0 0 0 0 0 0 0 0]
长度为:10

2.2 切片容量

2.2.1 初始化指定容量的切片

  • cap可选,指容量。

说明:

  • len是目前的成员数
  • cap是切片的上限

每增加 一个成员,len 值加1,成员数达到cap值后,cap值翻倍。

  • 语法
slice1 := make([]type, len, cap)
  • 语法示例
names  := make([]string,3,5)

2.2.2 查看切片长度 len()

  • 语法
cap(SliceName)
  • 示例
package mainimport "fmt"func main() {names  := make([]string,3,5)fmt.Printf("切片长度为:%d,容量为:%d",len(names),cap(names))
}

结果打印

切片长度为:3,容量为:5

3 切片赋值

3.1 直接赋值

  • 语法示例

在函数内我们用:在赋值的同时也声明了切片(只用=仅赋值但不能声明切片)

names :=[]string{"刘备","关羽","张飞" }
  • 完整示例
package main
import "fmt"func main() {names := []string{"刘备","关羽","张飞"}fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names))
}

结果显示

打印切片:[刘备 关羽 张飞]
长度为:3
容量为:3

3.2 引用数组给切片赋值

  • 语法
s := arr[:]
  • 示例
package mainimport "fmt"func main() {namesArray := [3]string{"刘备","关羽","张飞"} //定义一个数组names  := namesArray[:]  //声明切片并用数组给切片赋值fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names))
}

执行结果为:

打印切片:[刘备 关羽 张飞]
长度为:3
容量为:3

3.3 引用数组某区间给切片赋值

前提:设N为起始位置,到第M个成员。

3.3.1 从数组位置N个取到第M个元素,赋值给切片

- 语法

s := arr[N:M]

- 示例

  • 需求:从元素的位置1(刘备是位置0,关羽是位置1),取到第3个成员(第一个成员是刘备,第二个是关羽,第三个是张飞)
  • 预计:切片将取到 关羽、张飞两个成员。
  • 代码如下
package mainimport "fmt"func main() {namesArray := [5]string{"刘备","关羽","张飞","赵云","诸葛亮"} //定义一个数组names  := namesArray[1:3]fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names))
}
  • 结果打印
打印切片:[关羽 张飞]
长度为:2
容量为:4
  • 说明

长度是2,因为我们取到了两个成员:关羽、张飞
容量是4,这是从起始位置1(关羽)起,计算到数组结尾(诸葛亮),一共四个位置。

虽然没有取到赵云和诸葛亮,但是容量已经加进来了

3.3.2 从数组位置N取到结尾,赋值给切片

- 语法

s := arr[N:]

- 示例

  • 代码
package mainimport "fmt"func main() {namesArray := [5]string{"刘备","关羽","张飞","赵云","诸葛亮"} //定义一个数组names  := namesArray[1:]fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names))
}
  • 结果显示
打印切片:[关羽 张飞 赵云 诸葛亮]
长度为:4
容量为:4
  • 说明
    长度是4,因为我们取到了4个成员:关羽、张飞、赵云、诸葛亮
    容量是4,这是从起始位置1(关羽)起,计算到数组结尾(诸葛亮),一共四个位置。

3.3.3 从开头取到第M个元素,赋值给切片

- 语法

s := arr[:M]

- 示例

  • 需求:从开头(位置0)取到第二个成员(关羽)
package mainimport "fmt"func main() {namesArray := [5]string{"刘备","关羽","张飞","赵云","诸葛亮"} //定义一个数组names  := namesArray[:3]fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names))
}

结果打印

打印切片:[刘备 关羽 张飞]
长度为:3
容量为:5
  • 说明
    长度是3,因为我们取到了3个成员:刘备、关羽、张飞
    容量是5,这是从起始位置0(刘备)起,计算到数组结尾(诸葛亮),一共四个位置。

3.4 通过切片赋值给切片

说明:通过切片s初始化切片s1

s2 := s1[N:M]

方法同数组赋值给切片

4. 空切片

4.1 仅声明的切片为空

package mainimport "fmt"func main() {var names []stringfmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))if names == nil {fmt.Printf("切片是空的")}else {fmt.Println("切片不为空")}
}
  • 结果
打印切片:[]
长度为:0
容量为:0
切片是空的

4.2 初始容量为0的切片不为空

package mainimport "fmt"func main() {var names = make([]string,0,0)fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))if names == nil {fmt.Println("切片是空的")}else {fmt.Println("切片不为空")}
}

结果打印

打印切片:[]
长度为:0
容量为:0
切片不为空

5. append()

- 语法

  • 语法
func append(slice []Type, elems ...Type) []Type
  • 语法示例
names = append(names,"赵云")

- 示例1(添加一个成员)

  • 代码
package mainimport "fmt"func main() {names := []string{"刘备","关羽","张飞"} fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))names = append(names,"赵云")fmt.Printf("==================\n添加成员后:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
}
  • 结果
原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
==================
添加成员后:[刘备 关羽 张飞 赵云]
长度为:4
容量为:6
  • 说明:

结果可见,当成员达到容量上限后,再添加成员,长度增加一,但是容量会翻倍。

- 示例2(添加多个成员)

我们再继续添加成员,也想验证一下长度和容量的变化。

  • 代码
package mainimport "fmt"func main() {names := []string{"刘备","关羽","张飞"} fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))names = append(names,"赵云")fmt.Printf("==================\n添加成员后:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))names = append(names,"马超","黄忠","魏延")fmt.Printf("==================\n添加成员后:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
}
  • 结果
原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
==================
添加成员后:[刘备 关羽 张飞 赵云]
长度为:4
容量为:6
==================
添加成员后:[刘备 关羽 张飞 赵云 马超 黄忠 魏延]
长度为:7
容量为:12
  • 说明

可以看到,成员再次超过容量时,容量在当前容量的基础上翻倍。

- 示例3(添加成员赋值给新切片)

  • 代码
package mainimport "fmt"func main() {names := []string{"刘备","关羽","张飞"}fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))names2 := append(names,"赵云")fmt.Printf("==================\n新切片:%+v\n长度为:%d\n容量为:%d\n",names2,len(names2),cap(names2))fmt.Printf("==================\n再次打印原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
}
  • 结果显示
原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
==================
新切片:[刘备 关羽 张飞 赵云]
长度为:4
容量为:6
==================
再次打印原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
  • 说明:

结果可见,append对于原切片并不会造成影响。

6. copy() 函数

- 语法

func copy(dst []Type, src []Type) int

返回成功拷贝了多少个元素

- 示例1(新切片长度 >= 原切片长度)

  • 代码
package mainimport "fmt"func main() {names := []string{"刘备","关羽","张飞"}fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))names2 := make([]string,4,4)num := copy(names2,names)fmt.Printf("==================\n新切片:%+v\n拷贝了%d个元素\n长度为:%d\n容量为:%d\n",names2,num,len(names2),cap(names2))fmt.Printf("==================\n再次打印原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
}
  • 结果
原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
==================
新切片:[刘备 关羽 张飞 ]
拷贝了3个元素
长度为:4
容量为:4
==================
再次打印原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
  • 说明

如上可见,初始化长度为4,拷贝了3个元素,但是我们可以看到新切片最后有一个空格,是第3和第4个元素的分隔符,只是第四个元素为空

- 示例2 (新切片长度 < 原切片长度)

  • 代码
package mainimport "fmt"func main() {names := []string{"刘备","关羽","张飞"}fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))names2 := make([]string,2,4)num := copy(names2,names)fmt.Printf("==================\n新切片:%+v\n拷贝了%d个元素\n长度为:%d\n容量为:%d\n",names2,num,len(names2),cap(names2))fmt.Printf("==================\n再次打印原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
}
  • 结果显示
原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
==================
新切片:[刘备 关羽]
拷贝了2个元素
长度为:2
容量为:4
==================
再次打印原切片:[刘备 关羽 张飞]
长度为:3
容量为:3

- 示例2 (新切未初始化)

新切片未初始化的结果类似于初始化长度为0的切片

  • 代码
package mainimport "fmt"func main() {names := []string{"刘备","关羽","张飞"} fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))var names2 []stringif names2 == nil{fmt.Println("==================\nnames2 为空")}else{fmt.Println("==================\nname2 不为空")}num := copy(names2,names)fmt.Printf("新切片:%+v\n拷贝了%d个元素\n长度为:%d\n容量为:%d\n",names2,num,len(names2),cap(names2))fmt.Printf("==================\n再次打印原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
}
  • 结果
原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
==================
names2 为空
新切片:[]
拷贝了0个元素
长度为:0
容量为:0
==================
再次打印原切片:[刘备 关羽 张飞]
长度为:3
容量为:3

在这里插入图片描述


http://www.ppmy.cn/news/820.html

相关文章

【目标检测】Faster R-CNN论文代码复现过程解读(含源代码)

目录&#xff1a;Faster R-CNN论文代码复现过程解读Faster R-CNN代码使用说明书&#xff08;分享在github上&#xff09;一、代码的地址二、我的配置环境三、参数值文件下载四、VOC数据集下载五、模型训练步骤&#xff08;1&#xff09;训练VOC0712数据集1.数据集的准备2.数据集…

Android 11.0 设置默认8时区和默认24小时制

目录 1.概述 2.设置默认8时区和默认24小时制的核心类 3.设置默认8时区和默认24小时制的核

【日期时间的计算NSDate Objective-C语言】

一、计算时间 1.比如,什么时候用这个计算时间呢 NSDate *date = [NSDate new]; NSLog(@“%@”,date); 我们知道,这个时候,它打印的时间是什么时间,是不是当前的时间啊, 我想得到,在当前系统时间之后5000秒以后的时间 5000秒以后,在当前时间的基础之上, 这时候,…

AutoJs7打包薅羊毛时间版

AutoJs7打包薅羊毛时间版 一、准备工作&#xff1a; autojs7 app 下载地址&#xff1a;Auto.js Pro7.apk - 蓝奏云薅羊毛时间版 下载地址&#xff1a; 亚丁号---文件下载 安卓手机一部外加数据线&#xff08; Type-C或者USB&#xff09;&#xff0c;最好是安卓7的系统。电脑…

Unity 如何实现框选游戏战斗单位

文章目录&#x1f354; Preface✨ 如何在屏幕坐标系内绘制框选框&#x1f389; 根据框选范围定位其在世界坐标系中对应的区域&#x1f947; 在该区域内进行物理检测&#x1f354; Preface 本文简单介绍如何实现即时战略游戏中框选战斗单位的功能&#xff0c;如图所示&#xff…

Mybatis入门

详细的Mybatis介绍/使用&#xff0c;可以访问&#xff1a; 地址&#xff1a;mybatis – MyBatis 3 | 简介 目录 一、Mybatis介绍 二、依赖 三、什么是rowmapper 四、Mybatis demo 演示 4.1 背景 4.2 JDBC执行sql的流程 &Mybatis 关键要素 4.3 项目的整体结构&…

第二十章《Java Swing》第5节:常用组件

窗体上的按钮、标签、文本框等都被称为“窗体组件”,简称“组件”。大部分组件都是Jcomponent类的子类,而Jcomponent又是Container的子类、Container又是Component的子类。这3个类中所定义的方法都会都会被组件各种组件继承下来,因此大部分组件都有相同的方法,这些方法如表…

详解:进程程序替换

目录一、前言二、什么是进程程序替换&#xff1f;三、进程程序替换的原理四、为什么要进行进程程序替换&#xff1f;五、如何进行进程程序替换&#xff1f;(常见进程程序替换系统调用接口)六、利用所学综合知识实现一个shell总结一、前言 一般情况下&#xff0c;对应的语言写的…