注意: Declare slice or make slice?不能回答我的问题,因为它比较 slice 声明与make slice,而我的问题比较 slice 文字与make slice。该问题的答案很简单,因为裸 slice 声明会创建一个nil slice ,但是,如果您仔细阅读下面的问题,我根本不会创建nil slice 。
有两种方法可以创建 slice 并将其附加到 slice 。我的以下代码将两种方式分别显示为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)
创建空 slice 的两种方法是否等效?他们在任何情况下都会改变行为吗?
最佳答案
我修改了您的示例
// 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()
),但是没有-跳入sources表明makeslice()
也返回基于&zerobase
的 slice : if size == 0 {
return unsafe.Pointer(&zerobase)
}
因此,这两个片段都提供了相同的 slice 结构,其中数据指针设置为zerobase
。
关于go - slice 文字和make slice之间在行为上有区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63493026/