为了账号安全,请及时绑定邮箱和手机立即绑定

切片文字和制作切片之间的行为有区别吗?

切片文字和制作切片之间的行为有区别吗?

Go
温温酱 2022-06-27 09:34:48
它比较了切片声明与制作切片,而我的问题比较了切片文字与制作切片。这个问题有一个简单的答案,因为一个裸切片声明会创建一个 nil 切片,但是,如果您仔细阅读下面的问题,我根本不会创建一个 nil 切片。有两种方法可以创建切片并附加到切片。我下面的代码显示了Example 1和两种方式Example 2。package mainimport (    "fmt")func main() {    // Example 1    a := []int{}    fmt.Printf("len(a): %d; cap(a): %d; a: %v\n", len(a), cap(a), a)    a = append(a, 10, 20, 30, 40, 50)    fmt.Printf("len(a): %d; cap(a): %d; a: %v\n", len(a), cap(a), a)        // Example 2    b := make([]int, 0)    fmt.Printf("len(b): %d; cap(b): %d; b: %v\n", len(b), cap(b), b)    b = append(b, 10, 20, 30, 40, 50)    fmt.Printf("len(b): %d; cap(b): %d; b: %v\n", len(b), cap(b), b)}输出:len(a): 0; cap(a): 0; a: []len(a): 5; cap(a): 6; a: [10 20 30 40 50]len(b): 0; cap(b): 0; b: []len(b): 5; cap(b): 6; b: [10 20 30 40 50]两种创建空切片的方法都是[]int{}等效make([]int, 0)的吗?在任何情况下,他们的行为会有所不同吗?
查看完整描述

1 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

我修改了你的例子


    // Example 1

    a := []int{}

    pa := &a

  

    // Example 2

    b := make([]int, 0)

    pb := &b


    runtime.KeepAlive(pa)

    runtime.KeepAlive(pb)


它被编译为:


*** main.go#12   >    a := []int{}

0x4e56a9    488d0538bb1100          lea rax, ptr [runtime.zerobase]

0x4e56b0    4889442470          mov qword ptr [rsp+0x70], rax

0x4e56b5    8400                test byte ptr [rax], al

0x4e56b7    eb00                jmp 0x4e56b9

0x4e56b9    4889842418010000        mov qword ptr [rsp+0x118], rax

0x4e56c1    0f57c0              xorps xmm0, xmm0

0x4e56c4    0f11842420010000        movups xmmword ptr [rsp+0x120], xmm0

*** main.go#13   >    pa := &a

0x4e56cc    488d842418010000        lea rax, ptr [rsp+0x118]

0x4e56d4    4889442460          mov qword ptr [rsp+0x60], rax

*** main.go#16   >    b := make([]int, 0)

0x4e56d9    488d0520020100          lea rax, ptr [__image_base__+1005824]

0x4e56e0    48890424            mov qword ptr [rsp], rax

0x4e56e4    0f57c0              xorps xmm0, xmm0

0x4e56e7    0f11442408          movups xmmword ptr [rsp+0x8], xmm0

0x4e56ec    e8bf49f6ff          call $runtime.makeslice

0x4e56f1    488b442418          mov rax, qword ptr [rsp+0x18]

0x4e56f6    4889842400010000        mov qword ptr [rsp+0x100], rax

0x4e56fe    0f57c0              xorps xmm0, xmm0

0x4e5701    0f11842408010000        movups xmmword ptr [rsp+0x108], xmm0

*** main.go#17   >    pb := &b

0x4e5709    488d842400010000        lea rax, ptr [rsp+0x100]

0x4e5711    4889442458          mov qword ptr [rsp+0x58], rax


似乎会make([]int, 0)导致堆分配(通过$runtime.makeslice()),但没有 - 深入研究源表明makeslice()也返回&zerobase基于 - 的切片:


    if size == 0 {

        return unsafe.Pointer(&zerobase)

    }

因此,两个片段都给出了相同的切片结构,其中数据指针设置为zerobase。


查看完整回答
反对 回复 2022-06-27
  • 1 回答
  • 0 关注
  • 122 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号