欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 15分钟学 Go 第 14 天:切片

15分钟学 Go 第 14 天:切片

2024/10/24 12:03:36 来源:https://blog.csdn.net/weixin_40780178/article/details/143138584  浏览:    关键词:15分钟学 Go 第 14 天:切片

第14天:切片

学习目标

在今天的课程中,我们将学习Go语言中的切片,重点是切片的定义、使用、动态数组的特性及其在实际编程中的应用。通过实例和流程图,帮助你深入理解切片的工作原理与最佳实践。

一、切片的概念

切片是Go语言中一种重要的数据结构,提供了比数组更灵活的操作方式。切片是对数组的封装,使得数组的长度可以动态变化。

特点

  • 动态大小:切片的长度可以在运行时改变。
  • 引用类型:切片是一种引用数据类型,对切片的修改会影响其底层数组。
  • 包含指针、长度和容量:切片包含了指向底层数组的指针、切片的长度和切片的容量(可以容纳的元素个数)。

二、切片的定义与初始化

切片可以通过以下方式定义和初始化:

2.1 使用 make() 函数

make() 用于创建切片并分配内存:

slice := make([]int, 5) // 创建一个长度为5的整型切片
2.2 使用字面量初始化

切片可以通过字面量来直接初始化:

slice := []string{"Apple", "Banana", "Cherry"}
2.3 从数组创建切片

可以从数组中提取一个切片:

arr := [5]int{1, 2, 3, 4, 5}
sliceFromArr := arr[1:4] // 得到切片 [2, 3, 4]

三、切片的属性

切片有三个主要属性:

  1. 长度(Length):切片当前包含的元素数量,可以用 len() 函数获取。
  2. 容量(Capacity):切片可以容纳的最大元素数量,使用 cap() 函数获取。
  3. 指针(Pointer):指向切片底层数组的首地址。

四、切片的使用

4.1 创建与访问切片

以下是一个创建和访问切片的示例代码:

package mainimport ("fmt"
)func main() {// 使用 make 创建长度为5的整数切片numbers := make([]int, 5)fmt.Println("初始切片:", numbers) // 输出 [0 0 0 0 0]// 访问并修改切片元素numbers[0] = 10numbers[1] = 20fmt.Println("修改后的切片:", numbers) // 输出 [10 20 0 0 0]
}
4.2 切片的扩展

切片可以通过内置的 append() 函数动态扩展:

numbers = append(numbers, 30) // 添加一个新元素
fmt.Println("添加元素后的切片:", numbers) // 输出 [10 20 0 0 0 30]

五、切片的遍历

切片的遍历和数组类似,可以使用 for 循环和 range 来实现:

5.1 使用传统的 for 循环
for i := 0; i < len(numbers); i++ {fmt.Printf("Index: %d, Value: %d\n", i, numbers[i])
}
5.2 使用 range 循环
for index, value := range numbers {fmt.Printf("Index: %d, Value: %d\n", index, value)
}

六、切片的长度和容量

切片的长度和容量可以通过 len()cap() 函数获取:

fmt.Println("切片的长度:", len(numbers)) // 输出切片当前的长度
fmt.Println("切片的容量:", cap(numbers))  // 输出切片底层数组的容量

七、切片的零值

切片的零值为 nil,表示未初始化的切片。可以通过检查切片是否为 nil 来判断切片是否已分配。

var s []int
if s == nil {fmt.Println("切片是 nil") // 输出 "切片是 nil"
}

八、切片的复制

切片可以使用 copy() 函数进行复制:

source := []int{1, 2, 3}
destination := make([]int, len(source))
copy(destination, source)
fmt.Println("源切片:", source)         // 输出 [1 2 3]
fmt.Println("目标切片:", destination) // 输出 [1 2 3]

九、切片的切片

切片可以从其他切片中创建新的切片:

subSlice := numbers[1:4] // 从 numbers 切割出新的切片
fmt.Println("子切片:", subSlice) // 输出 [20 0 0]

十、切片与数组的区别

特性数组切片
大小固定动态
类型数组类型切片类型
引用类型值类型引用类型
内存分配静态动态

十一、实际应用场景

切片在许多现实编程问题中非常有用,比如存储来自用户输入的数据、处理多个数据项等。

示例:处理用户输入的切片
package mainimport ("fmt"
)func main() {var names []stringvar input stringfmt.Println("输入名字(输入'结束'以退出):")for {fmt.Scanln(&input)if input == "结束" {break}names = append(names, input)}fmt.Println("你输入的名字:", names)
}

十二、切片和内存

切片在动态扩展时,底层数组可能需要重新分配。Go会在运行时管理内存,当切片的容量不足时,会分配一个更大的底层数组,并将原有数据复制过去。这个过程可能会导致性能上升陡峭,因此在定义切片时可以提前设置适当的容量。

s := make([]int, 0, 10) // 指定初始容量为10
for i := 0; i < 15; i++ {s = append(s, i) // 会触发扩展
}

十三、常见问题解答

Q1: 切片的容量如何决定?

A: 切片的容量是由底层数组的大小决定的,初始时由 make() 指定,之后根据需要动态扩展。

Q2: 切片可以包含不同类型的元素吗?

A: 不可以,切片必须包含相同类型的元素。不同类型元素可以使用接口切片实现,但不推荐。

Q3: 增加切片元素时是否会影响性能?

A: 是的,当切片的容量不足时,重新分配底层数组和复制元素会造成性能开销,建议在初始化时根据预估大小设置切片的容量。

十四、流程图

下面是一个示例程序的运行流程图:

+--------------------+
|       main         |
+--------------------+
| Initialize slice   |
| Loop to read input |
| Append to slice    |
| Print final slice  |
+--------------------+

十五、总结

通过今天的学习,我们了解了切片的定义、使用方法及其在动态数组方面的灵活性。我们还讨论了切片的遍历、复制、切割及其在实际应用中的重要性。切片是Go语言中不可或缺的组成部分,掌握切片将帮助你在开发中更高效地管理数据。


怎么样今天的内容还满意吗?再次感谢观众老爷的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com