// go 1.9.5 src/runtime/slice.go:82
func growslice(et *_type, old slice, cap int) slice {
// ……
newcap := old.cap
doublecap := newcap + newcap
if cap > doublecap {
newcap = cap
} else {
if old.len < 1024 {
newcap = doublecap
} else {
for newcap < cap {
newcap += newcap / 4
}
}
}
// ……
capmem = roundupsize(uintptr(newcap) * ptrSize)
newcap = int(capmem / ptrSize)
}
arr1:=[]int{1,2,3}
arr2:=[]int{4,5}
append(arr1, arr2...)
//slice
slice = append(slice, elem1, elem2)
slice = append(slice, anotherSlice...)
//字节序列
// As a special case, it is legal(合法的) to append a string to a byte slice, like this:
slice = append([]byte("hello "), "world"...)
//类似的用法:
//写文件
fmt.Fprintln(os.Stdout, a...)
//函数传参
//不定参数
func test(i int, arr ...int) {
fmt.Printf("%T, %v", arr, arr) //[]int, [2 3]
}
func main() {
test(1, 2, 3) //不定参数
}
//传数组
func test(arr ...int) {
fmt.Printf("%T, %v", arr, arr) //[]int, [1 2 3]
}
func main() {
arr := []int{1, 2, 3}
test(arr...)
}
func main() {
// 从切片中删除元素
a := []int{30, 31, 32, 33, 34, 35, 36, 37}
// 要删除索引为2的元素
a = append(a[:2], a[3:]...)
fmt.Println(a) //[30 31 33 34 35 36 37]
}
// 从数组/切片获取
arr = [i,j,k]
len = j-i
cap = k-i
// 一个例子
x:= [...]int{0,1,2,3,4,5,6,7,8,9}
操作 得到的切片 len cap 备注
-------------+--------------------------+----+------+------------------------------
x[:] [0 1 2 3 4 5 6 7 8 9] 10 10 x[0:len(x)]
x[2:5] [2 3 4] 3 8
x[2:5:7] [2 3 4] 3 5
x[4:] [4 5 6 7 8 9] 6 6 x[4:len(x)]
x[:4] [0 1 2 3] 4 10 x[0:4]
x[:4:6] [0 1 2 3] 4 6 x[0:4:6]
使用 arr = [i,j], 注 这里的默认cap,是原始arr的长度-i
使用arr = [i,j,k]
使用arr = [i,j,k], 设置j=k, 即len=cap的好处: 修改切片内容时, 避免影响其他切片.
slice只能和nil比较
slice的赋值
切片是一个结构体, 切片在64bit系统下占用24bytes. 与切片关联的数据存放在底层数组里,不属于切片本身.
所以将切片赋值到任意变量时, 对底层数组的大小都不会有影响, 赋值时只会复制切片本身, 不会涉及底层数组里数据.
Go 语言的函数参数传递,只有值传递,没有引用传递。
函数形参是一个局部变量, 调用函数时, 会将变量拷贝一份, 赋值给函数形参.
这里slice的拷贝, 仅仅是拷贝slice的结构体, 不会涉及与slice关联的底层数组的数据.
// 函数foo接收一个整型切片,并返回这个切片
func foo(slice []int) []int {
...
return slice
}
func main(){
// 分配包含100万个整型值的切片
slice := make([]int, 1e6)
// 将slice传递到函数foo
slice = foo(slice)
}
func main() {
// copy()复制切片
a := []int{1, 2, 3, 4, 5}
c := make([]int, 5, 5)
copy(c, a) //使用copy()函数将切片a中的元素复制到切片c
fmt.Println(a) //[1 2 3 4 5]
fmt.Println(c) //[1 2 3 4 5]
c[0] = 1000 //互不干扰
fmt.Println(a) //[1 2 3 4 5]
fmt.Println(c) //[1000 2 3 4 5]
}
copy([1,2,3], [4,5]) // [4,5,3]
copy([1,2,3], [4,5,6,7]) // [4,5,6]
func main() {
s:= []int{0,1,2,3,4,5,6,7,8,9}
s1:=s[5:8]
n:=copy(s[4:],s1) // 在同一底层数组的不同区间复制
fmt.Println(n,s)
s2:=make([]int,6) // 在不同数组间复制
n=copy(s2,s)
fmt.Println(n,s2)
}
func main() {
b:=make([]byte,3)
n:=copy(b, "abcde")
fmt.Println(n,b) //3 [97 98 99]
}
func main() {
arr := []int{1, 2, 3}
fmt.Printf("%p\n", &arr[0])
fmt.Printf("%p\n", &arr[1])
fmt.Printf("%p\n", &arr[2])
}
//0xc00000c420
//0xc00000c428
//0xc00000c430
func main() {
arr := []int{1, 2, 3}
for k, v := range arr {
fmt.Printf("v ptr: %p, elem prt: %p\n", &v, &arr[k])
}
}
//v ptr: 0xc0000140c0, elem prt: 0xc00000c420
//v ptr: 0xc0000140c0, elem prt: 0xc00000c428
//v ptr: 0xc0000140c0, elem prt: 0xc00000c430
type user struct {
name string
age int
}
func main() {
//初始化users
users := []user{
{"m1", 1},
{"m2", 2},
{"m3", 3},
}
//初始化m
m := map[int]*user{}
for k, v := range users {
//1. 为v开辟地址空间 0xc0000044a0
// fmt.Printf("%p\n", &v) //0xc0000044a0
//2. 将users的每一项值的副本,放到这个地址空间里
m[k] = &v //v本身是一个固定的内存地址空间
}
//遍历m
for _, v := range m {
fmt.Println(v.name, v.age)
}
}
//m3 3
//m3 3
//m3 3
func main() {
arr := [...]int{0, 1, 2, 3}
fmt.Printf("%p\n", &arr) //0xc00000c420
fmt.Println(&arr[0]) //0xc00000c420
}
&arr取的是结构体实例的地址
arr的%p取的是slice关联的底层数组首元素地址
//main.go
package main
import "fmt"
func main() {
arr := make([]int, 0)
arr = append(arr, 1)
fmt.Println(arr)
}
$ go tool compile -S main.go
os.(*File).close STEXT dupok nosplit size=26 args=0x18 locals=0x0
0x0000 00000 (<autogenerated>:1) TEXT os.(*File).close(SB), DUPOK|NOSPLIT|ABIInternal, $0-24
0x0000 00000 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x0000 00000 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0000 00000 (<autogenerated>:1) FUNCDATA $2, gclocals·9fb7f0986f647f17cb53dda1484e0f7a(SB)
0x0000 00000 (<autogenerated>:1) PCDATA $0, $1
0x0000 00000 (<autogenerated>:1) PCDATA $1, $1
0x0000 00000 (<autogenerated>:1) MOVQ ""..this+8(SP), AX
0x0005 00005 (<autogenerated>:1) MOVQ (AX), AX
0x0008 00008 (<autogenerated>:1) PCDATA $0, $0
0x0008 00008 (<autogenerated>:1) PCDATA $1, $0
0x0008 00008 (<autogenerated>:1) MOVQ AX, ""..this+8(SP)
0x000d 00013 (<autogenerated>:1) XORPS X0, X0
0x0010 00016 (<autogenerated>:1) MOVUPS X0, "".~r0+16(SP)
0x0015 00021 (<autogenerated>:1) JMP os.(*file).close(SB)
0x0000 48 8b 44 24 08 48 8b 00 48 89 44 24 08 0f 57 c0 H.D$.H..H.D$..W.
0x0010 0f 11 44 24 10 e9 00 00 00 00 ..D$......
rel 22+4 t=8 os.(*file).close+0
"".main STEXT size=251 args=0x0 locals=0x58
0x0000 00000 (main.go:5) TEXT "".main(SB), ABIInternal, $88-0
0x0000 00000 (main.go:5) MOVQ (TLS), CX
0x0009 00009 (main.go:5) CMPQ SP, 16(CX)
0x000d 00013 (main.go:5) JLS 241
0x0013 00019 (main.go:5) SUBQ $88, SP
0x0017 00023 (main.go:5) MOVQ BP, 80(SP)
0x001c 00028 (main.go:5) LEAQ 80(SP), BP
0x0021 00033 (main.go:5) FUNCDATA $0, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0021 00033 (main.go:5) FUNCDATA $1, gclocals·568470801006e5c0dc3947ea998fe279(SB)
0x0021 00033 (main.go:5) FUNCDATA $2, gclocals·bfec7e55b3f043d1941c093912808913(SB)
0x0021 00033 (main.go:5) FUNCDATA $3, "".main.stkobj(SB)
0x0021 00033 (main.go:6) PCDATA $0, $1
0x0021 00033 (main.go:6) PCDATA $1, $0
0x0021 00033 (main.go:6) LEAQ type.int(SB), AX
0x0028 00040 (main.go:6) PCDATA $0, $0
0x0028 00040 (main.go:6) MOVQ AX, (SP)
0x002c 00044 (main.go:6) XORPS X0, X0
0x002f 00047 (main.go:6) MOVUPS X0, 8(SP)
0x0034 00052 (main.go:6) CALL runtime.makeslice(SB)
0x0039 00057 (main.go:6) PCDATA $0, $1
0x0039 00057 (main.go:6) MOVQ 24(SP), AX
0x003e 00062 (main.go:7) PCDATA $0, $2
0x003e 00062 (main.go:7) LEAQ type.int(SB), CX
0x0045 00069 (main.go:7) PCDATA $0, $1
0x0045 00069 (main.go:7) MOVQ CX, (SP)
0x0049 00073 (main.go:7) PCDATA $0, $0
0x0049 00073 (main.go:7) MOVQ AX, 8(SP)
0x004e 00078 (main.go:7) XORPS X0, X0
0x0051 00081 (main.go:7) MOVUPS X0, 16(SP)
0x0056 00086 (main.go:7) MOVQ $1, 32(SP)
0x005f 00095 (main.go:7) CALL runtime.growslice(SB)
0x0064 00100 (main.go:7) PCDATA $0, $1
0x0064 00100 (main.go:7) MOVQ 40(SP), AX
0x0069 00105 (main.go:7) MOVQ 48(SP), CX
0x006e 00110 (main.go:7) MOVQ 56(SP), DX
0x0073 00115 (main.go:7) MOVQ $1, (AX)
0x007a 00122 (main.go:8) PCDATA $0, $0
0x007a 00122 (main.go:8) MOVQ AX, (SP)
0x007e 00126 (main.go:7) LEAQ 1(CX), AX
0x0082 00130 (main.go:8) MOVQ AX, 8(SP)
0x0087 00135 (main.go:8) MOVQ DX, 16(SP)
0x008c 00140 (main.go:8) CALL runtime.convTslice(SB)
0x0091 00145 (main.go:8) PCDATA $0, $1
0x0091 00145 (main.go:8) MOVQ 24(SP), AX
0x0096 00150 (main.go:8) PCDATA $1, $1
0x0096 00150 (main.go:8) XORPS X0, X0
0x0099 00153 (main.go:8) MOVUPS X0, ""..autotmp_13+64(SP)
0x009e 00158 (main.go:8) PCDATA $0, $2
0x009e 00158 (main.go:8) LEAQ type.[]int(SB), CX
0x00a5 00165 (main.go:8) PCDATA $0, $1
0x00a5 00165 (main.go:8) MOVQ CX, ""..autotmp_13+64(SP)
0x00aa 00170 (main.go:8) PCDATA $0, $0
0x00aa 00170 (main.go:8) MOVQ AX, ""..autotmp_13+72(SP)
0x00af 00175 (<unknown line number>) NOP
0x00af 00175 ($GOROOT/src/fmt/print.go:274) PCDATA $0, $1
0x00af 00175 ($GOROOT/src/fmt/print.go:274) MOVQ os.Stdout(SB), AX
0x00b6 00182 ($GOROOT/src/fmt/print.go:274) PCDATA $0, $2
0x00b6 00182 ($GOROOT/src/fmt/print.go:274) LEAQ go.itab.*os.File,io.Writer(SB), CX
0x00bd 00189 ($GOROOT/src/fmt/print.go:274) PCDATA $0, $1
0x00bd 00189 ($GOROOT/src/fmt/print.go:274) MOVQ CX, (SP)
0x00c1 00193 ($GOROOT/src/fmt/print.go:274) PCDATA $0, $0
0x00c1 00193 ($GOROOT/src/fmt/print.go:274) MOVQ AX, 8(SP)
0x00c6 00198 ($GOROOT/src/fmt/print.go:274) PCDATA $0, $1
0x00c6 00198 ($GOROOT/src/fmt/print.go:274) PCDATA $1, $0
0x00c6 00198 ($GOROOT/src/fmt/print.go:274) LEAQ ""..autotmp_13+64(SP), AX
0x00cb 00203 ($GOROOT/src/fmt/print.go:274) PCDATA $0, $0
0x00cb 00203 ($GOROOT/src/fmt/print.go:274) MOVQ AX, 16(SP)
0x00d0 00208 ($GOROOT/src/fmt/print.go:274) MOVQ $1, 24(SP)
0x00d9 00217 ($GOROOT/src/fmt/print.go:274) MOVQ $1, 32(SP)
0x00e2 00226 ($GOROOT/src/fmt/print.go:274) CALL fmt.Fprintln(SB)
0x00e7 00231 (<unknown line number>) MOVQ 80(SP), BP
0x00ec 00236 (<unknown line number>) ADDQ $88, SP
0x00f0 00240 (<unknown line number>) RET
0x00f1 00241 (<unknown line number>) NOP
0x00f1 00241 (main.go:5) PCDATA $1, $-1
0x00f1 00241 (main.go:5) PCDATA $0, $-1
0x00f1 00241 (main.go:5) CALL runtime.morestack_noctxt(SB)
0x00f6 00246 (main.go:5) JMP 0
0x0000 64 48 8b 0c 25 00 00 00 00 48 3b 61 10 0f 86 de dH..%....H;a....
0x0010 00 00 00 48 83 ec 58 48 89 6c 24 50 48 8d 6c 24 ...H..XH.l$PH.l$
0x0020 50 48 8d 05 00 00 00 00 48 89 04 24 0f 57 c0 0f PH......H..$.W..
0x0030 11 44 24 08 e8 00 00 00 00 48 8b 44 24 18 48 8d .D$......H.D$.H.
0x0040 0d 00 00 00 00 48 89 0c 24 48 89 44 24 08 0f 57 .....H..$H.D$..W
0x0050 c0 0f 11 44 24 10 48 c7 44 24 20 01 00 00 00 e8 ...D$.H.D$ .....
0x0060 00 00 00 00 48 8b 44 24 28 48 8b 4c 24 30 48 8b ....H.D$(H.L$0H.
0x0070 54 24 38 48 c7 00 01 00 00 00 48 89 04 24 48 8d T$8H......H..$H.
0x0080 41 01 48 89 44 24 08 48 89 54 24 10 e8 00 00 00 A.H.D$.H.T$.....
0x0090 00 48 8b 44 24 18 0f 57 c0 0f 11 44 24 40 48 8d .H.D$..W...D$@H.
0x00a0 0d 00 00 00 00 48 89 4c 24 40 48 89 44 24 48 48 .....H.L$@H.D$HH
0x00b0 8b 05 00 00 00 00 48 8d 0d 00 00 00 00 48 89 0c ......H......H..
0x00c0 24 48 89 44 24 08 48 8d 44 24 40 48 89 44 24 10 $H.D$.H.D$@H.D$.
0x00d0 48 c7 44 24 18 01 00 00 00 48 c7 44 24 20 01 00 H.D$.....H.D$ ..
0x00e0 00 00 e8 00 00 00 00 48 8b 6c 24 50 48 83 c4 58 .......H.l$PH..X
0x00f0 c3 e8 00 00 00 00 e9 05 ff ff ff ...........
rel 5+4 t=16 TLS+0
rel 36+4 t=15 type.int+0
rel 53+4 t=8 runtime.makeslice+0
rel 65+4 t=15 type.int+0
rel 96+4 t=8 runtime.growslice+0
rel 141+4 t=8 runtime.convTslice+0
rel 161+4 t=15 type.[]int+0
rel 178+4 t=15 os.Stdout+0
rel 185+4 t=15 go.itab.*os.File,io.Writer+0
rel 227+4 t=8 fmt.Fprintln+0
rel 242+4 t=8 runtime.morestack_noctxt+0
go.cuinfo.packagename. SDWARFINFO dupok size=0
0x0000 6d 61 69 6e main
go.info.fmt.Println$abstract SDWARFINFO dupok size=42
0x0000 04 66 6d 74 2e 50 72 69 6e 74 6c 6e 00 01 01 11 .fmt.Println....
0x0010 61 00 00 00 00 00 00 11 6e 00 01 00 00 00 00 11 a.......n.......
0x0020 65 72 72 00 01 00 00 00 00 00 err.......
rel 19+4 t=28 go.info.[]interface {}+0
rel 27+4 t=28 go.info.int+0
rel 37+4 t=28 go.info.error+0
go.loc.os.(*File).close SDWARFLOC dupok size=0
go.info.os.(*File).close SDWARFINFO dupok size=55
0x0000 03 6f 73 2e 28 2a 46 69 6c 65 29 2e 63 6c 6f 73 .os.(*File).clos
0x0010 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e...............
0x0020 00 00 01 9c 00 00 00 00 01 0f 7e 72 30 00 01 ec ..........~r0...
0x0030 01 00 00 00 00 00 00 .......
rel 18+8 t=1 os.(*File).close+0
rel 26+8 t=1 os.(*File).close+26
rel 36+4 t=29 gofile..<autogenerated>+0
rel 49+4 t=28 go.info.error+0
go.range.os.(*File).close SDWARFRANGE dupok size=0
go.isstmt.os.(*File).close SDWARFMISC dupok size=0
0x0000 04 05 01 10 02 05 00 .......
go.loc."".main SDWARFLOC size=134
0x0000 ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 ................
0x0010 3e 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00 >.......d.......
0x0020 07 00 50 93 08 93 08 93 08 69 00 00 00 00 00 00 ..P......i......
0x0030 00 73 00 00 00 00 00 00 00 07 00 50 93 08 93 08 .s.........P....
0x0040 93 08 73 00 00 00 00 00 00 00 82 00 00 00 00 00 ..s.............
0x0050 00 00 08 00 50 93 08 93 08 51 93 08 82 00 00 00 ....P....Q......
0x0060 00 00 00 00 91 00 00 00 00 00 00 00 08 00 93 08 ................
0x0070 50 93 08 51 93 08 00 00 00 00 00 00 00 00 00 00 P..Q............
0x0080 00 00 00 00 00 00 ......
rel 8+8 t=1 "".main+0
go.info."".main SDWARFINFO size=74
0x0000 03 22 22 2e 6d 61 69 6e 00 00 00 00 00 00 00 00 ."".main........
0x0010 00 00 00 00 00 00 00 00 00 01 9c 00 00 00 00 01 ................
0x0020 0b 61 72 72 00 06 00 00 00 00 00 00 00 00 06 00 .arr............
0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0040 00 00 00 00 00 00 00 08 00 00 ..........
rel 9+8 t=1 "".main+0
rel 17+8 t=1 "".main+251
rel 27+4 t=29 gofile../root/code/main.go+0
rel 38+4 t=28 go.info.[]int+0
rel 42+4 t=28 go.loc."".main+0
rel 47+4 t=28 go.info.fmt.Println$abstract+0
rel 51+8 t=1 "".main+175
rel 59+8 t=1 "".main+231
rel 67+4 t=29 gofile../root/code/main.go+0
go.range."".main SDWARFRANGE size=0
go.isstmt."".main SDWARFMISC size=0
0x0000 04 13 04 0e 03 07 01 0c 02 05 01 05 02 07 01 1a ................
0x0010 02 05 01 16 02 04 01 04 02 05 01 05 02 05 01 1e ................
0x0020 02 07 01 2c 02 05 01 0a 02 0a 00 ...,.......
runtime.gcbits.01 SRODATA dupok size=1
0x0000 01 .
type..namedata.*interface {}- SRODATA dupok size=16
0x0000 00 00 0d 2a 69 6e 74 65 72 66 61 63 65 20 7b 7d ...*interface {}
type.*interface {} SRODATA dupok size=56
0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 ................
0x0010 4f 0f 96 9d 00 08 08 36 00 00 00 00 00 00 00 00 O......6........
0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0030 00 00 00 00 00 00 00 00 ........
rel 24+8 t=1 runtime.algarray+80
rel 32+8 t=1 runtime.gcbits.01+0
rel 40+4 t=5 type..namedata.*interface {}-+0
rel 48+8 t=1 type.interface {}+0
runtime.gcbits.02 SRODATA dupok size=1
0x0000 02 .
type.interface {} SRODATA dupok size=80
0x0000 10 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 ................
0x0010 e7 57 a0 18 02 08 08 14 00 00 00 00 00 00 00 00 .W..............
0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
rel 24+8 t=1 runtime.algarray+144
rel 32+8 t=1 runtime.gcbits.02+0
rel 40+4 t=5 type..namedata.*interface {}-+0
rel 44+4 t=6 type.*interface {}+0
rel 56+8 t=1 type.interface {}+80
type..namedata.*[]interface {}- SRODATA dupok size=18
0x0000 00 00 0f 2a 5b 5d 69 6e 74 65 72 66 61 63 65 20 ...*[]interface
0x0010 7b 7d {}
type.*[]interface {} SRODATA dupok size=56
0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 ................
0x0010 f3 04 9a e7 00 08 08 36 00 00 00 00 00 00 00 00 .......6........
0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0030 00 00 00 00 00 00 00 00 ........
rel 24+8 t=1 runtime.algarray+80
rel 32+8 t=1 runtime.gcbits.01+0
rel 40+4 t=5 type..namedata.*[]interface {}-+0
rel 48+8 t=1 type.[]interface {}+0
type.[]interface {} SRODATA dupok size=56
0x0000 18 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 ................
0x0010 70 93 ea 2f 02 08 08 17 00 00 00 00 00 00 00 00 p../............
0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0030 00 00 00 00 00 00 00 00 ........
rel 24+8 t=1 runtime.algarray+0
rel 32+8 t=1 runtime.gcbits.01+0
rel 40+4 t=5 type..namedata.*[]interface {}-+0
rel 44+4 t=6 type.*[]interface {}+0
rel 48+8 t=1 type.interface {}+0
type..namedata.*[1]interface {}- SRODATA dupok size=19
0x0000 00 00 10 2a 5b 31 5d 69 6e 74 65 72 66 61 63 65 ...*[1]interface
0x0010 20 7b 7d {}
type.*[1]interface {} SRODATA dupok size=56
0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 ................
0x0010 bf 03 a8 35 00 08 08 36 00 00 00 00 00 00 00 00 ...5...6........
0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0030 00 00 00 00 00 00 00 00 ........
rel 24+8 t=1 runtime.algarray+80
rel 32+8 t=1 runtime.gcbits.01+0
rel 40+4 t=5 type..namedata.*[1]interface {}-+0
rel 48+8 t=1 type.[1]interface {}+0
type.[1]interface {} SRODATA dupok size=72
0x0000 10 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 ................
0x0010 50 91 5b fa 02 08 08 11 00 00 00 00 00 00 00 00 P.[.............
0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0040 01 00 00 00 00 00 00 00 ........
rel 24+8 t=1 runtime.algarray+144
rel 32+8 t=1 runtime.gcbits.02+0
rel 40+4 t=5 type..namedata.*[1]interface {}-+0
rel 44+4 t=6 type.*[1]interface {}+0
rel 48+8 t=1 type.interface {}+0
rel 56+8 t=1 type.[]interface {}+0
""..inittask SNOPTRDATA size=32
0x0000 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
0x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
rel 24+8 t=1 fmt..inittask+0
type..namedata.*[]int- SRODATA dupok size=9
0x0000 00 00 06 2a 5b 5d 69 6e 74 ...*[]int
type.*[]int SRODATA dupok size=56
0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 ................
0x0010 1b 31 52 88 00 08 08 36 00 00 00 00 00 00 00 00 .1R....6........
0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0030 00 00 00 00 00 00 00 00 ........
rel 24+8 t=1 runtime.algarray+80
rel 32+8 t=1 runtime.gcbits.01+0
rel 40+4 t=5 type..namedata.*[]int-+0
rel 48+8 t=1 type.[]int+0
type.[]int SRODATA dupok size=56
0x0000 18 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 ................
0x0010 8e 66 f9 1b 02 08 08 17 00 00 00 00 00 00 00 00 .f..............
0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0030 00 00 00 00 00 00 00 00 ........
rel 24+8 t=1 runtime.algarray+0
rel 32+8 t=1 runtime.gcbits.01+0
rel 40+4 t=5 type..namedata.*[]int-+0
rel 44+4 t=6 type.*[]int+0
rel 48+8 t=1 type.int+0
go.itab.*os.File,io.Writer SRODATA dupok size=32
0x0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0010 44 b5 f3 33 00 00 00 00 00 00 00 00 00 00 00 00 D..3............
rel 0+8 t=1 type.io.Writer+0
rel 8+8 t=1 type.*os.File+0
rel 24+8 t=1 os.(*File).Write+0
go.itablink.*os.File,io.Writer SRODATA dupok size=8
0x0000 00 00 00 00 00 00 00 00 ........
rel 0+8 t=1 go.itab.*os.File,io.Writer+0
type..importpath.fmt. SRODATA dupok size=6
0x0000 00 00 03 66 6d 74 ...fmt
gclocals·e6397a44f8e1b6e77d0f200b4fba5269 SRODATA dupok size=10
0x0000 02 00 00 00 03 00 00 00 01 00 ..........
gclocals·69c1753bd5f81501d95132d08af04464 SRODATA dupok size=8
0x0000 02 00 00 00 00 00 00 00 ........
gclocals·9fb7f0986f647f17cb53dda1484e0f7a SRODATA dupok size=10
0x0000 02 00 00 00 01 00 00 00 00 01 ..........
gclocals·568470801006e5c0dc3947ea998fe279 SRODATA dupok size=10
0x0000 02 00 00 00 02 00 00 00 00 02 ..........
gclocals·bfec7e55b3f043d1941c093912808913 SRODATA dupok size=11
0x0000 03 00 00 00 02 00 00 00 00 01 03 ...........
"".main.stkobj SRODATA dupok size=24
0x0000 01 00 00 00 00 00 00 00 f0 ff ff ff ff ff ff ff ................
0x0010 00 00 00 00 00 00 00 00 ........
rel 16+8 t=1 type.[1]interface {}+0
Go 语言汇编 FUNCDATA 和 PCDATA 是编译器产生的,用于保存一些和垃圾收集相关的信息,我们先不用 care。
// 只关心下call, 看下go代码调用了runtime哪些函数
[root@VM_115_23_centos ~/code]# go tool compile -S main.go|grep -i call
0x0034 00052 (main.go:6) CALL runtime.makeslice(SB) //创建slice
0x005f 00095 (main.go:7) CALL runtime.growslice(SB) //扩容slice
0x008c 00140 (main.go:8) CALL runtime.convTslice(SB) //类型转换
0x00e2 00226 ($GOROOT/src/fmt/print.go:274) CALL fmt.Fprintln(SB)//打印函数
0x00f1 00241 (main.go:5) CALL runtime.morestack_noctxt(SB) //栈内存扩容
// 小结:
arr := make([]int, 0) //调用runtime.makeslice(SB)
arr = append(arr, 1) //调用runtime.growslice(SB)
//功能: 计算当前切片占用的内存空间
// 并在堆上申请一片连续的内存
//内存空间 = 切片中元素大小 x 切片容量
func makeslice(et *_type, len, cap int) unsafe.Pointer { // 返回指向底层数组的指针
mem, overflow := math.MulUintptr(et.size, uintptr(cap))
if overflow || mem > maxAlloc || len < 0 || len > cap {
mem, overflow := math.MulUintptr(et.size, uintptr(len))
if overflow || mem > maxAlloc || len < 0 {
panicmakeslicelen()
}
panicmakeslicecap()
}
return mallocgc(mem, et, true) //用于申请内存的函数
}
// src/runtime/slice.go:82
func growslice(et *_type, old slice, cap int) slice {
// ……
newcap := old.cap
doublecap := newcap + newcap
if cap > doublecap {
newcap = cap
} else {
if old.len < 1024 {
newcap = doublecap
} else {
for newcap < cap {
newcap += newcap / 4
}
}
}
// ……
capmem = roundupsize(uintptr(newcap) * ptrSize)
newcap = int(capmem / ptrSize)
}
BP 与 SP 是寄存器,它保存的是栈上的地址,所以执行中可以对 SP 做运算找到下一个指令的位置;
BP(base pointer): 栈底指针, 表示函数栈开始的地方。
SP(stack pointer): 栈顶指针, 表示函数栈空间分配结束的地方
执行中可以对 SP 做运算找到下一个指令的位置.
栈被回收,只是改变了 SP 指向的位置,内存中的数据并不会清空,只有下次被分配使用的时候才会清空;
看下 main 函数栈帧的开始和收尾部分。
0x0013 00019 (main.go:5)SUBQ $96, SP
0x0017 00023 (main.go:5)MOVQ BP, 88(SP)
0x001c 00028 (main.go:5)LEAQ 88(SP), BP
…………………………
0x00d3 00211 (main.go:9)MOVQ 88(SP), BP
0x00d8 00216 (main.go:9)ADDQ $96, SP
RET
原文:https://www.cnblogs.com/iiiiiher/p/12258598.html