在Golang中,数组(Array)和切片(Slice)是两个核心的数据结构,它们在声明和定义时时,方法极为相似,但在资源分配、灵活度以及性能方面有着巨大的差异
首先,定义,数组是固定长度、同类型元素的集合。数组的长度在声明时指定,且不可更改。
其次,值类型,数组(array)是值类型,关于什么是值类型,什么是引用类型,大家可以去百度脑补一下,值类型是具体的值,引用类型则是某个值的指针,这一点区别于所有传统语言,从c/c++、java、c#、python、javascript无一例外,数组都是引用类型,
再有,性能高,元素存储在连续内存中,这样保证了数组内存中的连续性,每个元素的宽度的固定性,可以以极快的速度定位到数组中的指定元素
最后,简单,易于理解和使用。这使得数组看上去非常单纯,没有过多操作数组的内置方法,增加了整个代码的执行效率,我反复调强过,golang是一门重视效率的语言,它把系统资源的每一分钱都要花在刀刃上。
但是它的缺点是不够灵活,长度固定,复制开销大,传递时会复制整个数组,开销很大(它每创建一次副本,都是一次深拷贝),因此建议,长度过大的数组,尽量少赋值副本,实际项目中运用也非常少,适合存储固定数量的数据,例如棋盘、图像数据等。
请看示例代码
package main
import "fmt"
func main() {
// 定义一个长度为5的数组
var arr [5]int
arr[0] = 1
arr[1] = 2
arr[2] = 3
arr[3] = 4
arr[4] = 5
fmt.Println("Array:", arr)
// 传递数组
modifyArray(arr)
fmt.Println("After modifyArray:", arr) // 原数组未变化
}
func modifyArray(a [5]int) {
a[0] = 100 // 修改的是副本,而函数结束时,函数所占用的系统资源会一并销毁,在这个示例中, a这个数组,就像没有存在过一样
}再来看切片(slice),切片是对数组的一个动态视图。它由指向数组的指针、长度和容量组成。在动态数据和灵活性方面表现优越,适合大多数应用场景。
切片是引用类型:传递切片时只复制指针,不会复制整个数据。
创建切片需通过数组、切片本身或make函数创建。
切片的大小可变:可以根据需要增长或缩小,扩展时消耗资源。
优点是灵活性高,支持动态变化的大小。低开销,传递切片时只复制指针。
它的不足也很明显,动态扩展时可能引入性能开销。可能导致内存泄漏,如果不注意切片的共享。切片的动态增长是通过内部的扩容机制实现的,而频繁的切片扩容可能引起性能问题。在预知切片长度时,可以通过make函数提前分配足够的容量,避免多次扩容。因此,切片适合存储动态数据,例如用户输入、动态生成的列表、栈和队列等。
示例代码
package main
import "fmt"
func main() {
// 定义切片
slice := []int{1, 2, 3, 4, 5}
fmt.Println("Slice:", slice)
// 传递切片
modifySlice(slice)
fmt.Println("After modifySlice:", slice) // 切片被修改
}
func modifySlice(s []int) {
s[0] = 100 // 修改的是原切片
}通过解析Golang中的切片与数组,我们了解了它们的定义、初始化、区别以及实际应用。切片的动态增长特性使其在容器和数据封装方面非常强大,而数组则适用于大小固定且性能要求较高的场景。并且我们强调了切片作为函数参数的使用、注意切片的生命周期、避免频繁的切片扩容等方面的注意事项。深入理解和熟练运用切片与数组将使Golang程序更加高效、灵活和可维护。
















