这道 reslice 的题 简单,但原理你知晓吗?
2 年前
· 来自专栏
golang 每日一题
package main
func a() []int {
a1 := []int{3}
a2 := a1[1:]
return a2
func main() {
看到这个题, 你的第一反应是啥?
(A) 编译失败
(B) panic: runtime error: index out of range [1] with length 1
(C) []
(D) 其他
也许你的第一感觉是: 肯定能编译过, 但是运行时一定会panic的. 但事与愿违竟然能够正常运行, 结果是:[]
a1 和 a2 共享同样的底层数组, len(a1) = 1, a1[1]绝对会panic, 但是a[1:]却能正常输出, 这是为何?
解答
看下如下代码输出的结果是啥?
a1 := []int{3}
fmt.Printf("len:%d, cap:%d", len(a1), cap(a1))
fmt.Println("a[0:]", a1[0:])
fmt.Println("a[1:]", a1[1:])
fmt.Println("a[2:]", a1[2:])
输出:
len:1, cap:1
a[0:]: [1]
a[1:] []
panic: runtime error: slice bounds out of range [2:1]
看到这里是不是,已经有些端倪了
再看下汇编的执行情况
".a STEXT size=87 args=0x18 locals=0x18
// 省略...
0x0028 00040 (main.go:6) CALL runtime.newobject(SB)
0x002d 00045 (main.go:6) MOVQ 8(SP), AX // 将slice的数据首地址加载到AX寄存器
0x0032 00050 (main.go:6) MOVQ $3, (AX) // 把3放入到AX寄存器中, 也就是a1[0]
0x0039 00057 (main.go:8) MOVQ AX, "".~r0+32(SP)
0x003e 00062 (main.go:8) XORPS X0, X0 // 初始化 X0 寄存器