Go 编程 | 连载 11 - 复杂数据类型 Slice

简介: Go 编程 | 连载 11 - 复杂数据类型 Slice

一、切片 Slice

Go 语言数组的长度是不可变的,也就无法数组中添加元素,Go 提供了另一种长度可变的数组,既切片(动态数组),切片可以进行追加元素,相比数组来说更加灵活。

切片的定义

第一种定义方式

Go 切片的定义方式与数组非常类似,但是数组定义时需要指定数组长度,而切片定义时则无须指定长度。

func main() {
   // 定义切片
   var langs = []string{"Go", "Python", "Ruby", "Java"}
   framworks := []string{"Rails", "Gin", "Play"}
   fmt.Printf("%T, %T", langs, framworks)
}
复制代码

执行上述代码,输出结果如下:

[]string, []string
复制代码

与数组类型不同的是切片类型并不包含长度属性。

第二种定义方式

使用 make 函数也可以定义切片,make 函数还可以定义 map 以及 channel 数据类型并返回这些数据类型的实例。

func main() {
   // 定义切片
   lans := make([]string, 3)
   fmt.Printf("%T, %v, %v", lans, lans, len(lans))
   lans[0] = "Elixir"
   fmt.Printf("%T, %v, %v", lans, lans, len(lans))
}
复制代码

执行上述代码,输出结果如下:

[]string, [  ], 3
[]string, [Elixir  ], 3
复制代码

make 函数传入两个值,一个是类型,另一个是长度。

使用 make 函数定义切片时,切片中的元素为元素类型的默认值,切片是动态数组,也可以通过索引对元素进行修改。

第三种定义方式

可以通过 切片操作 来获取子数组,子数组的类型就是一个切片类型,这里要注意 切片操作切片类型 的区分。

func main() {
   // 通过数组获取切片
   lans := [3]string{"Elixir", "Scala", "Groovy"}
   // 获取子数组 
   jvm_lans := lans[1:]
   fmt.Printf("%T, %v, %v", jvm_lans, jvm_lans, len(jvm_lans))
}
复制代码

执行上述代码,输出结果如下:

[]string, [Scala Groovy], 2
复制代码

第四种定义方式

func main() {
   // 使用 new 函数定义切片
   webFrameworks := *new([]string)
   fmt.Printf("%T, %v, %v\n", webFrameworks, webFrameworks, len(webFrameworks))
   webFrameworks = append(webFrameworks, "Grails")
   fmt.Printf("%T, %v, %v", webFrameworks, webFrameworks, len(webFrameworks))
}
复制代码

执行上述代码,输出结果如下:

[]string, [], 0
[]string, [Grails], 1
复制代码

new 函数调用时会返回一个内存地址,而 *内存地址 可以获取内存地址指向的实例,append 函数可以对切片进行追加操作,根据输出结果可以确定,初始化时切片的长度为 1,追加一个元素之后切片的长度变为 2。

make 函数和 new 函数都可以定义切片,它们的区别如下:

  • make 和 new 都是用来分配内存的內建函数,且在堆上分配内存,make 即分配内存,也初始化内存;new只是将内存清零,并没有初始化内存。
  • make 返回的还是引用类型(实例)本身;而 new 返回的是指向类型的指针(内存地址)。
  • make 只能用来分配及初始化类型为 slice,map,channel;new 可以分配任意类型的数据。

切片是引用类型

数组是值类型,而切片是引用类型,同样可以通过在自定义函数中修改传入的切片类型的数据来验证切片是引用类型。

func main() {
   lans := []string{"Elixir", "Scala", "Ruby"}
   SliceHandler(lans)
   fmt.Println(lans)
}
func SliceHandler(sli []string) {
   fmt.Println(sli)
   for idx, item := range sli {
      sli[idx] = strings.ToUpper(item)
   }
   fmt.Println(sli)
}
复制代码

执行上述代码,输出结果如下:

[Elixir Scala Ruby]
[ELIXIR SCALA RUBY]
[ELIXIR SCALA RUBY]
复制代码

原切片中的元素被修改,说明切片是引用类型。

二、切片的操作

追加

切片的追加操作可以通过内置的 append 函数实现,该函数需要传入要追加的切片以及要追加的元素,可以追加一个元素,也可以追加多个元素。

func main() {
   lans := []string{"Elixir", "Scala", "Ruby"}
   fmt.Printf("%T, %v, %v\n", lans, lans, len(lans))
   lans = append(lans, "Groovy")
   fmt.Printf("%T, %v, %v\n", lans, lans, len(lans))
   lans = append(lans, "Python", "Go", "Java")
   fmt.Printf("%T, %v, %v\n", lans, lans, len(lans))
}
复制代码

执行上述代码,输出结果如下:

[]string, [Elixir Scala Ruby], 3
[]string, [Elixir Scala Ruby Groovy], 4
[]string, [Elixir Scala Ruby Groovy Python Go Java], 7


相关文章
|
1月前
|
数据库连接 Go 数据库
Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性
本文探讨了Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性;防御编程则强调在编码时考虑各种错误情况,确保程序健壮性。文章详细介绍了这两种技术在Go语言中的实现方法及其重要性,旨在提升软件质量和可靠性。
38 1
|
1月前
|
存储 编译器 Go
go语言中的变量、常量、数据类型
【11月更文挑战第3天】
36 9
|
1月前
|
数据采集 监控 Java
go语言编程学习
【11月更文挑战第3天】
42 7
|
1月前
|
Unix Linux Go
go进阶编程:Golang中的文件与文件夹操作指南
本文详细介绍了Golang中文件与文件夹的基本操作,包括读取、写入、创建、删除和遍历等。通过示例代码展示了如何使用`os`和`io/ioutil`包进行文件操作,并强调了错误处理、权限控制和路径问题的重要性。适合初学者和有经验的开发者参考。
|
2月前
|
Java 大数据 Go
Go语言:高效并发的编程新星
【10月更文挑战第21】Go语言:高效并发的编程新星
54 7
|
2月前
|
Go 数据处理 调度
Go语言中的并发模型:解锁高效并行编程的秘诀
本文将探讨Go语言中独特的并发模型及其在现代软件开发中的应用。通过深入分析 Goroutines 和 Channels,我们将揭示这一模型如何简化并行编程,提升应用性能,并改变开发者处理并发任务的方式。不同于传统多线程编程,Go的并发方法以其简洁性和高效性脱颖而出,为开发者提供了一种全新的编程范式。
|
7月前
|
编译器 Go C语言
go语言基本数据类型和变量
go语言基本数据类型和变量
59 0
|
Go 存储
02-Go语言数据类型与变量
Go基本类型 布尔型: bool - 长度: 1字节 - 取值范围: true,false - 注意事项: 不可以用数字代表true或false 整型: int/uint - 根据运行平台可能为32或64 8位整型:int8/uint8 - 长度: 1字节 - 取值范围: -128~127/0-25...
925 0
|
Go Java
Golang数据类型和变量
数据类型 先来介绍一下Golang的数据类型。 布尔型 bool类型代表逻辑值,有真值true和假值false两种取值。 整数类型 整数类型有如下几种,这些整数都是有符号的类型,它们的无符号版本是类型名前面添加u,例如uint32。
769 0
|
3天前
|
存储 监控 算法
员工上网行为监控中的Go语言算法:布隆过滤器的应用
在信息化高速发展的时代,企业上网行为监管至关重要。布隆过滤器作为一种高效、节省空间的概率性数据结构,适用于大规模URL查询与匹配,是实现精准上网行为管理的理想选择。本文探讨了布隆过滤器的原理及其优缺点,并展示了如何使用Go语言实现该算法,以提升企业网络管理效率和安全性。尽管存在误报等局限性,但合理配置下,布隆过滤器为企业提供了经济有效的解决方案。
31 8
员工上网行为监控中的Go语言算法:布隆过滤器的应用