数组和切片的区别
-
定义方式:
- 数组:使用固定长度来声明,并在声明时初始化具体的元素。例如:
var arr [5]int
或arr := [5]int{1, 2, 3, 4, 5}
- 切片:使用不指定长度的方式声明,并可以通过切片操作符(
[:]
)来从数组、切片或字符串中创建。例如:var slice []int
或slice := arr[1:3]
- 数组:使用固定长度来声明,并在声明时初始化具体的元素。例如:
-
长度是否固定:
- 数组:具有固定长度,创建时需要明确指定。
- 切片:长度是可变的,并且可以动态调整。
-
底层数据结构:
- 数组:在内存中以连续的块存储。
- 切片:是对数组的引用,并包含了长度(切片中的元素数目)和容量(底层数组中的元素数目)。
-
传递方式:
- 数组:以值的方式传递给函数时会进行一次完整的数组拷贝。
- 切片:以引用的方式传递给函数,避免了整个切片的拷贝,减少了内存开销。
-
长度信息:
- 数组:通过
len()
函数获取数组的长度。 - 切片:通过
len()
函数获取切片的长度,通过cap()
函数获取切片的容量。
- 数组:通过
在实际使用中,数组通常用于表示一组固定大小的相同类型的数据,而切片则更为灵活,用于处理可变长度的数据集合。
需要注意的是,切片可以基于数组创建,但数组并不等同于切片。当你使用切片操作符 [:]
对数组进行切片操作时,得到的结果是一个切片,而不是数组。
用reflect包来判断变量是数组还是切片
通过 reflect.TypeOf()
可以获取到变量的类型,然后通过 Kind()
方法可以获取到类型的种类。
arr := [5]int{1, 2, 3, 4, 5}
slice := []int{1, 2, 3, 4, 5}
// 判断数据类型
arrType := reflect.TypeOf(arr)
sliceType := reflect.TypeOf(slice)
// 输出结果
fmt.Println("arrType:", arrType)
//结果为 [5]int
fmt.Println("sliceType:", sliceType)
//结果为 []int
fmt.Println(arrType.Kind())
//结果为 array
fmt.Println(sliceType.Kind())
//结果为slice
}
运行结果: