注:本文是對golang-101-hacks中文翻譯。git
Go支持多維切片,再此只對二維切片切片作介紹。平常生活中一般會使用到二維切片,而多維彷佛並很少見。若是你常常使用多維切片,我的認爲代碼極不友好,也不容易維護,所以能夠試試有沒有更好的方法去解決多維的問題;另外的緣由是多維切片和二維切片的原理是同樣的,若是你對二維切片理解的很好,能夠作到一通百通。 查看下面的demogolang
package main
import "fmt"
func main() {
s := make([][]int, 2)
fmt.Println(len(s), cap(s), &s[0])
s[0] = []int{1, 2, 3}
fmt.Println(len(s[0]), cap(s[0]), &s[0][0])
s[1] = make([]int, 3, 5)
fmt.Println(len(s[1]), cap(s[1]), &s[1][0])
}
複製代碼
使用gdb作斷點調試數組
5 func main() {
(gdb) n
6 s := make([][]int, 2)
(gdb)
7 fmt.Println(len(s), cap(s), &s[0])
(gdb)
2 2 &[]
9 s[0] = []int{1, 2, 3}
(gdb) p &s
$1 = (struct [][]int *) 0xc82003fe70
(gdb) x/24xb 0xc82003fe70
0xc82003fe70: 0x40 0x02 0x01 0x20 0xc8 0x00 0x00 0x00
0xc82003fe78: 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc82003fe80: 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00
複製代碼
s是一個二維切片(起始內存地址是0xc82003fe70),同時它包含的元素也是切片,經過斷點查看元素:bash
(gdb) x/48xb 0xc820010240
0xc820010240: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010248: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010250: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010258: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010260: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010268: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
複製代碼
全部的內存內容都是0,繼續一步步往下執行:ui
(gdb) n
10 fmt.Println(len(s[0]), cap(s[0]), &s[0][0])
(gdb)
3 3 0xc82000e220
12 s[1] = make([]int, 3, 5)
複製代碼
如今,s已包含一個切片元素,查看它的底層數組:spa
(gdb) x/48xb 0xc820010240
0xc820010240: 0x20 0xe2 0x00 0x20 0xc8 0x00 0x00 0x00
0xc820010248: 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010250: 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010258: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010260: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010268: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
複製代碼
此時,s[0]的指針、長度和的容量發生了改變,與以前fmt.Println的輸出相同。 查看s[0]的底層數組:翻譯
(gdb) x/24xb 0xc82000e220
0xc82000e220: 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc82000e228: 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc82000e230: 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00
複製代碼
咱們可查看到3個元素1,2,3 同理查看s[1] Following the same method to check the s[1]:指針
(gdb) n
13 fmt.Println(len(s[1]), cap(s[1]), &s[1][0])
(gdb)
3 5 0xc820010270
14 }
(gdb) x/48xb 0xc820010240
0xc820010240: 0x20 0xe2 0x00 0x20 0xc8 0x00 0x00 0x00
0xc820010248: 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010250: 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010258: 0x70 0x02 0x01 0x20 0xc8 0x00 0x00 0x00
0xc820010260: 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010268: 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00
(gdb) x/40xb 0xc820010270
0xc820010270: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010278: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010280: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010288: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xc820010290: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
複製代碼
到此能夠看到s包含了它的slice元素的全部信息,而且s[1]的元素被初始化爲0。調試