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

它比较了切片声明与制作切片,而我的问题比较了切片文字与制作切片。这个问题有一个简单的答案,因为一个裸切片声明会创建一个 nil 切片,但是,如果您仔细阅读下面的问题,我根本不会创建一个 nil 切片。


有两种方法可以创建切片并附加到切片。我下面的代码显示了Example 1和两种方式Example 2。


package main


import (

    "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)的吗?在任何情况下,他们的行为会有所不同吗?


温温酱
浏览 124回答 1
1回答

泛舟湖上清波郎朗

我修改了你的例子    // 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], rax0x4e56b5    8400                test byte ptr [rax], al0x4e56b7    eb00                jmp 0x4e56b90x4e56b9    4889842418010000        mov qword ptr [rsp+0x118], rax0x4e56c1    0f57c0              xorps xmm0, xmm00x4e56c4    0f11842420010000        movups xmmword ptr [rsp+0x120], xmm0*** main.go#13   >    pa := &a0x4e56cc    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], rax0x4e56e4    0f57c0              xorps xmm0, xmm00x4e56e7    0f11442408          movups xmmword ptr [rsp+0x8], xmm00x4e56ec    e8bf49f6ff          call $runtime.makeslice0x4e56f1    488b442418          mov rax, qword ptr [rsp+0x18]0x4e56f6    4889842400010000        mov qword ptr [rsp+0x100], rax0x4e56fe    0f57c0              xorps xmm0, xmm00x4e5701    0f11842408010000        movups xmmword ptr [rsp+0x108], xmm0*** main.go#17   >    pb := &b0x4e5709    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。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go