slice 初始化和未初始化的区别

slice初始化和为初始化

  • 初始化为赋值之前是空气片
  • 为初始化为nil不能赋值
//未初始化的slice
package main
import (
    "fmt"
)
func main() {
    // 可以使用
    var s []string
    s = append(s, "a")
    fmt.Println(s)
}
  • s[0] = “a” 会报错
  • 这个是append内部实现了slice的自增,内部进行了make初始化。每次对slice的操作内部会产生一个新的数组,然后返回。
//初始化的slice
func main() {
	s :=make([]int,10)
	s[0] =1
	fmt.Println(s)
}
  • 初始化之后的slice可以为其赋值
  • 但是如果初始化容量为零(即超出容量)依然会painc:panic: runtime error: index out of range [0] with length 0

nil切片 和 空切片的比较

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	var   s1 []int
	var s2 =[]int{}
	var s3 =make([]int,0)
	//new 函数返回是指针类型,所以需要使用 * 号来解引用
	var s4 = *new([]int)

	var a1 = *(*[3]int)(unsafe.Pointer(&s1))
	var a2 = *(*[3]int)(unsafe.Pointer(&s2))
	var a3 = *(*[3]int)(unsafe.Pointer(&s3))
	var a4 = *(*[3]int)(unsafe.Pointer(&s4))

	fmt.Println(a1)
	fmt.Println(a2)
	fmt.Println(a3)
	fmt.Println(a4)
}
  • 其中输出为 [0 0 0] 的 s1 和 s4 变量就是「 nil 切片」,s2 和 s3 变量就是「空切片」。824634199592 这个值是一个特殊的内存地址

在这里插入图片描述

所有类型的「空切片」都共享这一个内存地址:

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	var s2 =[]int{}
	var s3 =make([]int,0)
	var a2 = *(*[3]int)(unsafe.Pointer(&s2))
	var a3 = *(*[3]int)(unsafe.Pointer(&s3))
	
	var s5 = make([]struct{x,y,z int},0)
	var a5 = *(*[3]int)(unsafe.Pointer(&s5))

	fmt.Println(a2)
	fmt.Println(a3)
	fmt.Println(a5)
}

在这里插入图片描述
用图形来表示「空切片」和「 nil 切片」如下:

在这里插入图片描述

「 nil 切片」和 「空切片」在使用上有什么区别

package main

import "fmt"

func main() {

	var s1 []int
	var s2 = []int{}
	fmt.Println(s1==nil)
	fmt.Println(s2==nil)

	fmt.Printf("%#v\n",s1)
	fmt.Printf("%#v\n",s2)

}
官方建议:统一使用「 nil 切片」

前者声明一个nil片值,而后者是非nil,但长度为零。它们在功能上是相等的——它们的len和cap都是零——但是nil片是首选的样式。

原文链接

知识点补充:

切片的底层是一个数组:
在这里插入图片描述
切片的表层是一个包含三个变量的结构体,当我们将一个切片赋值给另一个切片时,本质上是对切片表层结构体的浅拷贝。

type slcie struct{
array unsafe.Pointer
lenght int
capcity int
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值