一篇文章说清楚Golang 之切片与数组

切片和数组什么区别,这个问题经常会被问到,那么到底什么是切片和数组,他们之间有什么区别,一次性说的明明白白彻彻底底。

从本质上说,切片数组都是一种计算机中存储数据的一种结构,可以理解为一种容器。和变量的本质是一样的,只不过一个变量只能保存一个单独的数据,如果想保存多个数据,这种场景,我们就交给切片和数组 这类型的容器结构

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 前后的切片,然后 把 后者 添加到前者当中,成为一个新的切片,这个就是切片的删除。

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值