首页 > 其他分享 >Go笔记(六):切片

Go笔记(六):切片

时间:2023-04-14 09:03:33浏览次数:37  
标签:slice01 fmt 笔记 切片 slice02 Printf Go 长度

  切片是对数组的拓展,在Go中数组的长度一旦定义无法被修改,切片的长度是不固定的,可以理解为切片是一个可变长度数组,是一个有相同类型元素的可变长度序列。

1、声明切片

1.1、显示声明切片

1、语法

  声明切片语法如下:

var sclicename []type

2、示例代码

 1 package main
 2 
 3 import "fmt"
 4 
 5 // 方式一:声明/定义切片
 6 func defineSlice() {
 7    var slice01 []string
 8    var slice02 []int
 9    var arr01 [3]int
10 
11    fmt.Printf("slice01: %v, 长度:%v, 容量:%v\n", slice01, len(slice01), cap(slice01))
12    fmt.Printf("slice02: %v, 长度:%v, 容量:%v\n", slice02, len(slice02), cap(slice02))
13    fmt.Printf("arr01: %v\n, 长度:%v, 容量:%v\n", arr01, len(arr01), cap(arr01))
14 }
15 
16 func main() {
17    defineSlice()
18 }

  声明的切片(slice),默认切片的长度与容量为0。定义基本类型的切片,不会用其默认值填充切片。因为切片的长度是可变的,不像数组指定了长度,可以用基本类型的默认值填充。上述示例代码执行结果如下:

  

1.2、make() 函数创建切片

1、语法

  make()函数可以用来初始化 slice(切片)、Map。t 表示切片类型。

func make(t Type, size ...IntegerType) Type
  创建容量与数组长度相同的切片:
make([]type, length)

  创建容量与数组长度不同的切片:

make([]type, length, capacity)

  type:切片的类型

  length:数组的长度,切片的初始长度

  capacity:切片的容量值

2、示例代码

make函数创建的切片可以指定切片的数组长度len与容量capacity。

  当指定切片数组长度len与容量capacity为0时,与显示声明切片等价;

  当指定数组长度len与容量capacity相同并且大于0时,切片等价于数组,此时切片会对基本类型的切片设置默认值;

  当指定的数组长度len小于容量capacity时,基本类型切片会在数组长度部分设置基本类型的默认值。

 1 package main
 2 
 3 import "fmt"
 4 
 5 // 方式二:通过make声明切片
 6 func makeSlice() {
 7 
 8    // 等价于 var sliceEmpty []int
 9    var sliceEmpty = make([]int, 0)
10    fmt.Printf("sliceEmpty: %v, 长度:%v, 容量:%v\n", sliceEmpty, len(sliceEmpty), cap(sliceEmpty))
11 
12    // 指定长度的与容量的切片
13    var slice01 = make([]string, 2)
14    fmt.Printf("slice01: %v, 长度:%v, 容量:%v\n", slice01, len(slice01), cap(slice01))
15 
16    // 指定长度的与容量的切片 省略类型, 需要用 =
17    var slice02 = make([]int, 3)
18    fmt.Printf("slice02: 初始值:%v, 长度:%v, 容量:%v\n", slice02, len(slice02), cap(slice02))
19 
20    // 指定长度的与容量的切片 类型推导, 需要用 :=
21    slice03 := make([]bool, 2)
22    fmt.Printf("slice03: 初始值:%v, 长度:%v, 容量:%v\n", slice03, len(slice03), cap(slice03))
23 
24    // 创建指定容量的切片,capacity为 容量值;length为数组长度,也是切片的初始长度 -> make([]T, length, capacity)
25    slice04 := make([]bool, 3, 4)
26    fmt.Printf("slice04: 初始值:%v, 长度:%v, 容量%v\n", slice04, len(slice04), cap(slice04))
27 
28    // 创建指定容量的切片,capacity为 容量值;length为数组长度,也是切片的初始长度 -> make([]T, length, capacity)
29    slice05 := make([]bool, 0, 5)
30    fmt.Printf("slice05: 初始值:%v, 长度:%v, 容量%v\n", slice05, len(slice05), cap(slice05))
31 }
32 
33 func main() {
34    makeSlice()
35 }

  上述代码执行结果如下:

 

2、初始化切片

1、直接初始化

  声明切片的同时,初始化切片中的元素。

package main

import "fmt"

// 初始化切片方式一:直接初始化
func dirctInitSlice() {
   var slice01 = []int{4, 5, 6}
   fmt.Printf("slice01: %v, 长度:%v, 容量%v\n", slice01, len(slice01), cap(slice01))
   slice02 := []string{"hello", " ", "world"}
   fmt.Printf("slice02: %v, 长度:%v, 容量%v\n", slice02, len(slice02), cap(slice02))
}

func main() {
   dirctInitSlice()
}

  执行结果如下:

2、切片表达式初始化 切片

  切片的底层是数组,基于数组可通过切片表达式得到切片。切片表达式中low和high表示一个索引范围(左包含,右不包含),得到的切片长度=high-low,容量等于得到的切片的底层数组容量。
 1 package main
 2 
 3 import "fmt"
 4 
 5 // 初始化切片方式二:切片表达式
 6 func arrInitSlice() {
 7    arr := [...]int{1, 2, 3, 4, 5, 6, 7, 8}
 8    //取索引值3 -> 6, 左包含,右不包含
 9    slice01 := arr[3:7]
10    fmt.Printf("slice01: %v, 长度:%v, 容量%v\n", slice01, len(slice01), cap(slice01))
11    // 取索引值 0 -> 5
12    slice02 := arr[:6]
13    fmt.Printf("slice02: %v, 长度:%v, 容量%v\n", slice02, len(slice02), cap(slice02))
14    // 取索引值 2 -> 7
15    slice03 := arr[2:]
16    fmt.Printf("slice03: %v, 长度:%v, 容量%v\n", slice03, len(slice03), cap(slice03))
17    // 取出数组中的所有元素
18    slice04 := arr[:]
19    fmt.Printf("slice04: %v, 长度:%v, 容量%v\n", slice04, len(slice04), cap(slice04))
20 }
21 
22 func main() {
23    arrInitSlice()
24 }

  执行结果如下:

 

3、访问切片

1、切片的容量与长度

从上面的示例中已经知道

  切片的容量函数:cap()、切片的长度函数:len()

  具体的示例代码不再展示,参考上面的示例即可。

2、空切片的判断

  在Go中 nil 表示 空,相当于Java中的null。显示声明的切片,未做任何初始化操作,切片的数组长度与容量都是0,是空切片。通过make()函数创建的切片,即使数组长度与容量都是0,也不是空切片。验证代码如下:

 1 package main
 2 
 3 import "fmt"
 4 
 5 // 空切片的判断
 6 func emptySlice() {
 7    var slice01 []int
 8    fmt.Printf("显示声明 slice01 ==> 长度:%v,容量:%v\n", len(slice01), cap(slice01))
 9    if slice01 == nil {
10       fmt.Printf("slice01 ==> 空切片\n")
11    }
12 
13    slice02 := make([]int, 0)
14    fmt.Printf("make创建 slice02 ==> 长度:%v,容量:%v\n", len(slice02), cap(slice02))
15    if slice02 == nil {
16       fmt.Printf("slice02 ==> 空切片\n")
17    }else {
18       fmt.Printf("slice02 ==> 非空切片\n")
19    }
20 
21    slice03 := make([]int, 0, 5)
22    fmt.Printf("make创建 slice03 ==> 长度:%v,容量:%v\n", len(slice03), cap(slice03))
23    if slice03 == nil {
24       fmt.Printf("slice03 ==> 空切片\n")
25    }else {
26       fmt.Printf("slice03 ==> 非空切片\n")
27    }
28 
29    slice04 := make([]int, 2, 5)
30    fmt.Printf("make创建 slice04 ==> 长度:%v,容量:%v\n", len(slice04), cap(slice04))
31    if slice04 == nil {
32       fmt.Printf("slice04 ==> 空切片\n")
33    } else {
34       fmt.Printf("slice04 ==> 非空切片\n")
35    }
36 
37 }
38 
39 func main() {
40    emptySlice()
41 }

  执行结果如下:

 

4、遍历切片

4.1、for

 1 package main
 2 
 3 import "fmt"
 4 
 5 // 遍历切片方式一:通过切片长度访问切片元素
 6 func visitSlice01() {
 7    slice01 := []bool{false, true, true}
 8    for i := 0; i < len(slice01); i++ {
 9       if slice01[i] {
10          fmt.Println("Yes")
11       } else {
12          fmt.Println("No")
13       }
14    }
15 }
16 
17 func main() {
18    visitSlice01()
19 }

  执行结果如下:

 

4.2、for range

 1 package main
 2 
 3 import "fmt"
 4 
 5 // 遍历切片方式二:通过for range访问切片元素
 6 func visitSlice02() {
 7    slice01 := []string{"zs", "ls", "ww", "hz"}
 8    for i, v := range slice01 {
 9       fmt.Printf("下标:i: %v, 元素值:v: %v\n", i, v)
10    }
11    fmt.Println("-----------------------------")
12    for _, v := range slice01 {
13       fmt.Printf("元素值:v: %v\n", v)
14    }
15 }
16 
17 func main() {
18    visitSlice02()
19 }

  执行结果如下:

 

5、操作切片

  切片是动态的数组,可使用append()函数添加元素。

  切片是引用类型,通过赋值的方式会修改原有内容,可通过copy()函数拷贝切片。

5.1、添加

1、添加元素

 1 package main
 2 import "fmt"
 3 // 添加元素
 4 func addEleSlice01() {
 5     slice01 := []int{}
 6     slice01 = append(slice01, 1)
 7     slice01 = append(slice01, 2)
 8     slice01 = append(slice01, 3)
 9     slice01 = append(slice01, 4, 5, 6)
10     fmt.Printf("slice01: %v\n", slice01)
11 }
12 func main() {
13     addEleSlice01()
14 }

  执行结果如下:

2、添加切片

 1 package main
 2 
 3 import "fmt"
 4 
 5 // 添加切片
 6 func addSliceToSlice() {
 7    var slice01 = []string{"tom", "jack"}
 8    var slice02 []string
 9    slice02 = []string{"hello", "-", "world"}
10    slice03 := append(slice01, slice02...)
11    fmt.Printf("slice03: %v\n", slice03)
12    slice04 := append(slice01[:1], slice02[1:]...)
13    fmt.Printf("slice04: %v\n", slice04)
14 }
15 
16 func main() {
17    addSliceToSlice()
18 }

  执行结果如下:

  0

5.2、删除元素

  Go未提供删除切片元素的方法,但可以利用切片表达式删除元素。例如:从切片slice中删除索引为index的元素,slice = append(slice[:index], slice[index+1:]...)

 1 package main
 2 
 3 import "fmt"
 4 
 5 // 删除元素,利用切片表达式
 6 func delEleSlice() {
 7    slice01 := []int{1, 2, 3, 4, 5, 6}
 8    // 删除索引值为3的元素
 9    fmt.Printf("slice01[3]: %v\n", slice01[3])
10    slice02 := append(slice01[:3], slice01[4:]...)
11    fmt.Printf("slice02: %v\n", slice02)
12 }
13 
14 func main() {
15    delEleSlice()
16 }

  执行结果如下:

  0

5.3、更新元素

 1 package main
 2 
 3 import "fmt"
 4 
 5 // 更新执行下标的切片元素
 6 func updEleSlice() {
 7    slice01 := []int{1, 2, 3}
 8    fmt.Printf("upd before ==> slice01: %v\n", slice01)
 9    slice01[1] = 200
10    fmt.Printf("upd after ==> slice01: %v\n", slice01)
11 }
12 
13 func main() {
14    updEleSlice()
15 }

   执行结果如下:

  0

6、切片的拷贝

切片是引用类型,copy()函数是一个深拷贝,切片在使用copy函数时,需要用make函数创建申请内存。

  浅拷贝:将切片A的引用赋给切片B,当切片A元素值改变时,会影响切片B。

  深拷贝:将切片A的元素值拷贝到切片B的内存中,当切片A元素值改变时,不会影响切片B。

 1 package main
 2 
 3 import "fmt"
 4 
 5 // copy()函数,深拷贝
 6 func copySlice() {
 7    slice01 := []int{1, 2, 3}
 8    // 1、浅拷贝
 9    slice02 := slice01
10    // 2、深拷贝
11    // 未分配内存地址,采用此种方式声明slice03切片,copy(slice03, slice01)无效
12    var slice03 = []int{}
13    // 分配内存地址
14    slice04 := make([]int, 3)
15    copy(slice03, slice01)
16    copy(slice04, slice01)
17 
18    slice01[1] = 200
19    fmt.Printf("原切片:slice01: %v\n", slice01)
20    fmt.Printf("`:=`赋值切片 :slice02: %v\n", slice02)
21    fmt.Printf("显示声明切片:slice03: %v\n", slice03)
22    fmt.Printf("make()创建指定长度与容量切片:slice04: %v\n", slice04)
23 }
24 
25 func main() {
26    copySlice()
27 }

  执行结果如下:

  0  

标签:slice01,fmt,笔记,切片,slice02,Printf,Go,长度
From: https://www.cnblogs.com/RunningSnails/p/17317181.html

相关文章

  • pytest学习笔记
    pytest是python的一种单元测试框架,与python自带的unittest测试框架类似,但是比unittest框架使用起来更简洁,效率更高。根据pytest的官方网站介绍,它具有如下特点:非常容易上手,入门简单,文档丰富,文档中有很多实例可以参考能够支持简单的单元测试和复杂的功能测试支持参数化执行测......
  • Django笔记六之外键ForeignKey介绍
    本文首发于公众号:Hunter后端原文链接:Django笔记六之外键ForeignKey介绍这是一种一对多的字段类型,表示两张表之间的关联关系。本篇笔记的目录如下:on_deleterelated_namerelated_query_name外键字段的保存1、on_delete假设有两个application,app1和app2app1下的某......
  • Django笔记二十三之case、when操作条件表达式搜索、更新等操作
    本文首发于公众号:Hunter后端原文链接:Django笔记二十三之条件表达式搜索、更新等操作这一篇笔记将介绍条件表达式,就是如何在model的使用中根据不同的条件筛选数据返回。这个操作类似于数据库中ifelifelse的逻辑。以下是本篇笔记的目录:model和数据准备When和Case......
  • 烘焙笔记
    目录贝壳边贝壳边标准头大尾小大小均匀,纹路清晰收口要圆不留缝......
  • 虚幻引擎 4 学习笔记 [1] :蓝图编程 Demo
    虚幻引擎4学习笔记[1]:蓝图编程Demo​ 最近学习虚幻引擎,主要看的是Siki学院的课,课程链接:Unreal蓝图案例-基础入门-SiKi学院|SiKi学堂-unity|u3d|虚幻|ue4/5|java|python|人工智能|视频教程|在线课程(sikiedu.com)​ 以下为课程笔记:1.创建工程​ 选择蓝图,不带初......
  • ROS学习笔记(二)- 提供服务和调用服务
    书接上回-https://www.cnblogs.com/lihan829/p/17315435.html前面展示了ROS节点发布和订阅消息,这次展示如何提供服务和调用服务。提供服务和调用服务很好理解,概念和行为上并不深奥,就是远程过程调用,可类比为http接口的远程调用,grpc接口的远程调用等等。1,服务提供方,定义服务,服......
  • go语言学习-gin框架会话控制
    cookie介绍HTTP是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分两次请求是否由同一个客户端发出Cookie就是解决HTTP协议无状态的方案之一,中文是小甜饼的意思Cookie实际上就是服务器保存在浏览器上的一段信息。浏览器有了Cookie之后,每次向服务器发送请求时都会同......
  • 详解Django admin高级用法
    Django后台admin有大量的属性和方法,拥有强大的功能和自定义能力.通过完整的代码来看Djangoadmin的基础设置和高级用法,并结合form表单来实现深度自定义.简单使用如果只是使用admin自带的数据管理功能,只需要将模型注册到admin中,就可以实现.fromdjango.contribimportadmi......
  • GAMES101笔记-01
    前言:这篇以及未来的一系列随笔是根据b站上的GAMES101现代计算机图形学入门课程所写的笔记,但笔记的篇章并非和课程一一对应。比如这篇对应的是第二课~第三课的内容。并且整理时不一定会将推导过程全部列出,做成只有总结概括的内容也不是没有可能。 1.向量叉乘的矩阵表示:  ......
  • Go For Web:踏入Web大门的第一步——Web 的工作方式
    前言:本文作为解决如何通过Golang来编写Web应用这个问题的前瞻,对Golang中的Web基础部分进行一个简单的介绍。目前Go拥有成熟的Http处理包,所以我们去编写一个做任何事情的动态Web程序应该是很轻松的,接下来我们就去学习了解一些关于Web的相关基础,了解一些概念,以及......