切片和数组什么区别,这个问题经常会被问到,那么到底什么是切片和数组,他们之间有什么区别,一次性说的明明白白彻彻底底。
从本质上说,切片数组都是一种计算机中存储数据的一种结构,可以理解为一种容器。和变量的本质是一样的,只不过一个变量只能保存一个单独的数据,如果想保存多个数据,这种场景,我们就交给切片和数组 这类型的容器结构
1、什么是切片和数组
切片是一个可以动态分配大小的连续的内存空间,用于保存形同类型的数据。而数组是一个拥有固定长度的连续内存空间,固定长度就是指我们在申请一个数组的时候,就必须确定这个数组的大小,确定之后数组的大小是没办法改变的,我们只能修改数组内部元素,但无法改变数组大小。
数组的申明方式和赋值
var arr [3]string
arr[0]="1001"
arr[1]="1002"
arr[2]="1003"
数组的初始化
方法1:直接指定数组大小,指定后只能添加指定数量的元组。超出编译示错误
Invalid array index '3' (out of bounds for the 3-element array)
var names=[3]string{"tom","jerry","losy"}
方法2:数组大小直接用`...`表示, 然后自由赋值元组即可,其他的交给编译器。
var numbers = [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println(numbers)
切片的申明方式
方式1:通过关键字 var 申请
var slice []float32
方式2:通过make 申明
slice2 := make([]string, 5, 10)
这里案例是 申明字符串类型的切片,5 只是元素个数, 10 是预先分配的空间大小。
切片的初始化
var sli2 = []string{"one", "two", "thre"}
切片和数组访问遍历
再go语言当中, 通道、切片、数组、字符串 都可以用 for range 键值循环 进行遍历访问数据。
var str2 = "ABC"
var arr2 = [2]int{1, 2}
var sli2 = []string{"one", "two", "thre"}
for k, v := range str2 {
fmt.Println("string k:", k, " string v:", v, "\n")
}
for k, v := range arr2 {
fmt.Println("array k:", k, " arrayv:", v, "\n")
}
for k, v := range sli2 {
fmt.Println("slice k:", k, "slice v:", v, "\n")
}
}
3、切片和数组到底什么区别
1、数组大小不可变,而切片大小是可变的,可以动态扩容的。
2、数组是值传递类型、而切片是指针,什么意呢?
请看代码看完就明白了
package main
import "fmt"
func Demo1(sli []int, arr [3]int) {
sli[1] = 100
arr[1] = 100
}
func main() {
arr_1 := [3]int{1, 2, 3}
sli_1 := []int{1, 2, 3}
fmt.Println("arr_1修改前:", arr_1)
fmt.Println("sli_1修改前:", sli_1)
Demo1(sli_1, arr_1)
fmt.Println("arr_1修改后:", arr_1)
fmt.Println("sli_1修改后:", sli_1)
}
""""""
>>>
输出
arr_1修改前: [1 2 3]
sli_1修改前: [1 2 3]
arr_1修改后: [1 2 3]
sli_1修改后: [1 100 3]
代码案例中我们给一个函数传递传递两个参数,一个是切片,一个是数组,再函数的内部,我们对
切片和数组数组进行了修改元组的操作,我们看到原切片的值发生了变化,但原数组的值并没有发生变化,也就是修改的操作并没有影响到原数组。因为数组是值传递,函数中传递了一个数组是原数组的值拷贝,只是修改了拷贝的数组,对原来数组是没有任何影响的。
而切片传递的是指针,再函数内部修改了切片的值,就修改了原切片的值,原切片就发生了变化。
这是切片和数组最大最主要的区别。
4、切片和数组分别在什么场景用
如果我们非常明确的知道自己包保存的数据类型数据数量,后期不会增多,其实我们就可以申请数组来保存数据,能够节省内存的分配 。 如果我们不确定数据的数量,保存的数据是动态数据集,显然切片会更好更方便,而且切片是可以自动扩容。
5、切片和数组哪个更好
没有好与不好,只有在合适的场景用合适的数据结构。
6、拓展
1) 切片的元素添加
切片可以通过apend()函数进行数据元素的添加操作。
package main
import (
"fmt"
)
type User struct {
Name string
Age int
}
func main() {
var users []*User
u1 := &User{
Name: "tom",
Age: 18,
}
u2 := &User{
Name: "jerry",
Age: 20,
}
users = append(users, u1, u2)
for _, val := range users {
fmt.Println(val.Name)
}
}
2) 切片的元素删除
go语言当中 没有可以直接删除切片某个元素的方法,只能从删除的位置切分开,然后把前后两个切片拼接起来。
案例:
package main
import "fmt"
func main() {
var slice = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
fmt.Println(slice)
index := 4
slice = append(slice[:index], slice[index+1:]...)
fmt.Println(slice)
}
案例中,我们加入要删除 位置index=4 的元素,我们截取了 位置4 前后的切片,然后 把 后者 添加到前者当中,成为一个新的切片,这个就是切片的删除。