GO 语言从入门到放弃
Example1 (未完成)
package main
import (
"fmt"
)
func Foo(x interface{}) {
if x == nil {
fmt.Println("empty")
return
}
fmt.Println("non-empty")
}
func main() {
var x *int = nil
Foo(x)
}
根据interface是否包含method, 底层实现上有两种struct表示: iface\eface.
eface 表示不含 method,即 empty inteface.
Golong中大部分数据类型都可以抽象出_type
结构,
type eface struct {
_type *_type
data unsafe.Pointer
}
type _type struct {
size uintptr // type size
ptrdata uintptr // size of memory prefix holding all pointers
hash uint32 // hash of type; avoids computation in hash tables
tflag tflag // extra type information flags
align uint8 // alignment of variable with this type
fieldalign uint8 // alignment of struct field with this type
kind uint8 // enumeration for C
alg *typeAlg // algorithm table
gcdata *byte // garbage collection data
str nameOff // string form
ptrToThis typeOff // type for pointer to this type, may be zero
}
汇编:
nl a1.s
1 "".Foo t=1 size=480 value=0 args=0x10 locals=0x78
2 0x0000 00000 (a1.go:7) TEXT "".Foo(SB), $120-16 // 局部变量 120字节, 栈空间 16字节
3 0x0000 00000 (a1.go:7) MOVQ (TLS), CX
4 0x0009 00009 (a1.go:7) CMPQ SP, 16(CX)
5 0x000d 00013 (a1.go:7) JLS 467
6 0x0013 00019 (a1.go:7) SUBQ $120, SP // 分配栈
7 0x0017 00023 (a1.go:8) MOVQ "".x+128(FP), BX // 取arg0
8 0x001f 00031 (a1.go:8) CMPQ BX, $0
9 0x0023 00035 (a1.go:8) JNE 254
10 0x0029 00041 (a1.go:9) LEAQ go.string."empty"(SB), BX
11 0x0030 00048 (a1.go:9) MOVQ BX, "".autotmp_0000+80(SP)
12 0x0035 00053 (a1.go:9) MOVQ $5, "".autotmp_0000+88(SP)
13 0x003e 00062 (a1.go:9) MOVQ $0, BX
14 0x0040 00064 (a1.go:9) MOVQ BX, "".autotmp_0005+64(SP)
15 0x0045 00069 (a1.go:9) MOVQ BX, "".autotmp_0005+72(SP)
16 0x004a 00074 (a1.go:9) LEAQ "".autotmp_0005+64(SP), BX
17 0x004f 00079 (a1.go:9) CMPQ BX, $0
18 0x0053 00083 (a1.go:9) JEQ $1, 247
19 0x0059 00089 (a1.go:9) MOVQ $1, "".autotmp_0002+104(SP)
20 0x0062 00098 (a1.go:9) MOVQ $1, "".autotmp_0002+112(SP)
21 0x006b 00107 (a1.go:9) MOVQ BX, "".autotmp_0002+96(SP)
22 0x0070 00112 (a1.go:9) LEAQ type.string(SB), BX
23 0x0077 00119 (a1.go:9) MOVQ BX, (SP)
24 0x007b 00123 (a1.go:9) LEAQ "".autotmp_0000+80(SP), BX
25 0x0080 00128 (a1.go:9) MOVQ BX, 8(SP)
26 0x0085 00133 (a1.go:9) MOVQ $0, 16(SP)
27 0x008e 00142 (a1.go:9) CALL runtime.convT2E(SB)
28 0x0093 00147 (a1.go:9) MOVQ 24(SP), CX
29 0x0098 00152 (a1.go:9) MOVQ 32(SP), AX
30 0x009d 00157 (a1.go:9) MOVQ "".autotmp_0002+96(SP), BX
31 0x00a2 00162 (a1.go:9) MOVQ CX, "".autotmp_0006+48(SP)
32 0x00a7 00167 (a1.go:9) MOVQ CX, (BX)
33 0x00aa 00170 (a1.go:9) MOVQ AX, "".autotmp_0006+56(SP)
34 0x00af 00175 (a1.go:9) CMPB runtime.writeBarrier(SB), $0
35 0x00b6 00182 (a1.go:9) JNE $0, 227
36 0x00b8 00184 (a1.go:9) MOVQ AX, 8(BX)
37 0x00bc 00188 (a1.go:9) MOVQ "".autotmp_0002+96(SP), BX
38 0x00c1 00193 (a1.go:9) MOVQ BX, (SP)
39 0x00c5 00197 (a1.go:9) MOVQ "".autotmp_0002+104(SP), BX
40 0x00ca 00202 (a1.go:9) MOVQ BX, 8(SP)
41 0x00cf 00207 (a1.go:9) MOVQ "".autotmp_0002+112(SP), BX
42 0x00d4 00212 (a1.go:9) MOVQ BX, 16(SP)
43 0x00d9 00217 (a1.go:9) CALL fmt.Println(SB)
44 0x00de 00222 (a1.go:10) ADDQ $120, SP
45 0x00e2 00226 (a1.go:10) RET
46 0x00e3 00227 (a1.go:9) LEAQ 8(BX), R8
47 0x00e7 00231 (a1.go:9) MOVQ R8, (SP)
48 0x00eb 00235 (a1.go:9) MOVQ AX, 8(SP)
49 0x00f0 00240 (a1.go:9) CALL runtime.writebarrierptr(SB)
50 0x00f5 00245 (a1.go:9) JMP 188
51 0x00f7 00247 (a1.go:9) MOVL AX, (BX)
52 0x00f9 00249 (a1.go:9) JMP 89
53 0x00fe 00254 (a1.go:12) LEAQ go.string."non-empty"(SB), BX
54 0x0105 00261 (a1.go:12) MOVQ BX, "".autotmp_0001+80(SP)
55 0x010a 00266 (a1.go:12) MOVQ $9, "".autotmp_0001+88(SP)
56 0x0113 00275 (a1.go:12) MOVQ $0, BX
57 0x0115 00277 (a1.go:12) MOVQ BX, "".autotmp_0010+64(SP)
58 0x011a 00282 (a1.go:12) MOVQ BX, "".autotmp_0010+72(SP)
59 0x011f 00287 (a1.go:12) LEAQ "".autotmp_0010+64(SP), BX
60 0x0124 00292 (a1.go:12) CMPQ BX, $0
61 0x0128 00296 (a1.go:12) JEQ $1, 460
62 0x012e 00302 (a1.go:12) MOVQ $1, "".autotmp_0007+104(SP)
63 0x0137 00311 (a1.go:12) MOVQ $1, "".autotmp_0007+112(SP)
64 0x0140 00320 (a1.go:12) MOVQ BX, "".autotmp_0007+96(SP)
65 0x0145 00325 (a1.go:12) LEAQ type.string(SB), BX
66 0x014c 00332 (a1.go:12) MOVQ BX, (SP)
67 0x0150 00336 (a1.go:12) LEAQ "".autotmp_0001+80(SP), BX
68 0x0155 00341 (a1.go:12) MOVQ BX, 8(SP)
69 0x015a 00346 (a1.go:12) MOVQ $0, 16(SP)
70 0x0163 00355 (a1.go:12) CALL runtime.convT2E(SB)
71 0x0168 00360 (a1.go:12) MOVQ 24(SP), CX
72 0x016d 00365 (a1.go:12) MOVQ 32(SP), AX
73 0x0172 00370 (a1.go:12) MOVQ "".autotmp_0007+96(SP), BX
74 0x0177 00375 (a1.go:12) MOVQ CX, "".autotmp_0006+48(SP)
75 0x017c 00380 (a1.go:12) MOVQ CX, (BX)
76 0x017f 00383 (a1.go:12) MOVQ AX, "".autotmp_0006+56(SP)
77 0x0184 00388 (a1.go:12) CMPB runtime.writeBarrier(SB), $0
78 0x018b 00395 (a1.go:12) JNE $0, 440
79 0x018d 00397 (a1.go:12) MOVQ AX, 8(BX)
80 0x0191 00401 (a1.go:12) MOVQ "".autotmp_0007+96(SP), BX
81 0x0196 00406 (a1.go:12) MOVQ BX, (SP)
82 0x019a 00410 (a1.go:12) MOVQ "".autotmp_0007+104(SP), BX
83 0x019f 00415 (a1.go:12) MOVQ BX, 8(SP)
84 0x01a4 00420 (a1.go:12) MOVQ "".autotmp_0007+112(SP), BX
85 0x01a9 00425 (a1.go:12) MOVQ BX, 16(SP)
86 0x01ae 00430 (a1.go:12) CALL fmt.Println(SB)
87 0x01b3 00435 (a1.go:13) ADDQ $120, SP
88 0x01b7 00439 (a1.go:13) RET //
89 0x01b8 00440 (a1.go:12) LEAQ 8(BX), R8
90 0x01bc 00444 (a1.go:12) MOVQ R8, (SP)
91 0x01c0 00448 (a1.go:12) MOVQ AX, 8(SP)
92 0x01c5 00453 (a1.go:12) CALL runtime.writebarrierptr(SB)
93 0x01ca 00458 (a1.go:12) JMP 401
94 0x01cc 00460 (a1.go:12) MOVL AX, (BX)
95 0x01ce 00462 (a1.go:12) JMP 302
96 0x01d3 00467 (a1.go:12) NOP
97 0x01d3 00467 (a1.go:7) CALL runtime.morestack_noctxt(SB)
98 0x01d8 00472 (a1.go:7) JMP 0
99 0x0000 64 48 8b 0c 25 00 00 00 00 48 3b 61 10 0f 86 c0 dH..%....H;a....
100 0x0010 01 00 00 48 83 ec 78 48 8b 9c 24 80 00 00 00 48 ...H..xH..$....H
101 0x0020 83 fb 00 0f 85 d5 00 00 00 48 8d 1d 00 00 00 00 .........H......
102 0x0030 48 89 5c 24 50 48 c7 44 24 58 05 00 00 00 31 db H.\$PH.D$X....1.
103 0x0040 48 89 5c 24 40 48 89 5c 24 48 48 8d 5c 24 40 48 H.\$@H.\$HH.\$@H
104 0x0050 83 fb 00 0f 84 9e 00 00 00 48 c7 44 24 68 01 00 .........H.D$h..
105 0x0060 00 00 48 c7 44 24 70 01 00 00 00 48 89 5c 24 60 ..H.D$p....H.\$`
106 0x0070 48 8d 1d 00 00 00 00 48 89 1c 24 48 8d 5c 24 50 H......H..$H.\$P
107 0x0080 48 89 5c 24 08 48 c7 44 24 10 00 00 00 00 e8 00 H.\$.H.D$.......
108 0x0090 00 00 00 48 8b 4c 24 18 48 8b 44 24 20 48 8b 5c ...H.L$.H.D$ H.\
109 0x00a0 24 60 48 89 4c 24 30 48 89 0b 48 89 44 24 38 80 $`H.L$0H..H.D$8.
110 0x00b0 3d 00 00 00 00 00 75 2b 48 89 43 08 48 8b 5c 24 =.....u+H.C.H.\$
111 0x00c0 60 48 89 1c 24 48 8b 5c 24 68 48 89 5c 24 08 48 `H..$H.\$hH.\$.H
112 0x00d0 8b 5c 24 70 48 89 5c 24 10 e8 00 00 00 00 48 83 .\$pH.\$......H.
113 0x00e0 c4 78 c3 4c 8d 43 08 4c 89 04 24 48 89 44 24 08 .x.L.C.L..$H.D$.
114 0x00f0 e8 00 00 00 00 eb c5 89 03 e9 5b ff ff ff 48 8d ..........[...H.
115 0x0100 1d 00 00 00 00 48 89 5c 24 50 48 c7 44 24 58 09 .....H.\$PH.D$X.
116 0x0110 00 00 00 31 db 48 89 5c 24 40 48 89 5c 24 48 48 ...1.H.\$@H.\$HH
117 0x0120 8d 5c 24 40 48 83 fb 00 0f 84 9e 00 00 00 48 c7 .\$@H.........H.
118 0x0130 44 24 68 01 00 00 00 48 c7 44 24 70 01 00 00 00 D$h....H.D$p....
119 0x0140 48 89 5c 24 60 48 8d 1d 00 00 00 00 48 89 1c 24 H.\$`H......H..$
120 0x0150 48 8d 5c 24 50 48 89 5c 24 08 48 c7 44 24 10 00 H.\$PH.\$.H.D$..
121 0x0160 00 00 00 e8 00 00 00 00 48 8b 4c 24 18 48 8b 44 ........H.L$.H.D
122 0x0170 24 20 48 8b 5c 24 60 48 89 4c 24 30 48 89 0b 48 $ H.\$`H.L$0H..H
123 0x0180 89 44 24 38 80 3d 00 00 00 00 00 75 2b 48 89 43 .D$8.=.....u+H.C
124 0x0190 08 48 8b 5c 24 60 48 89 1c 24 48 8b 5c 24 68 48 .H.\$`H..$H.\$hH
125 0x01a0 89 5c 24 08 48 8b 5c 24 70 48 89 5c 24 10 e8 00 .\$.H.\$pH.\$...
126 0x01b0 00 00 00 48 83 c4 78 c3 4c 8d 43 08 4c 89 04 24 ...H..x.L.C.L..$
127 0x01c0 48 89 44 24 08 e8 00 00 00 00 eb c5 89 03 e9 5b H.D$...........[
128 0x01d0 ff ff ff e8 00 00 00 00 e9 23 fe ff ff cc cc cc .........#......
129 rel 5+4 t=14 +0
130 rel 44+4 t=13 go.string."empty"+0
131 rel 115+4 t=13 type.string+0
132 rel 143+4 t=6 runtime.convT2E+0
133 rel 177+4 t=13 runtime.writeBarrier+-1
134 rel 218+4 t=6 fmt.Println+0
135 rel 241+4 t=6 runtime.writebarrierptr+0
136 rel 257+4 t=13 go.string."non-empty"+0
137 rel 328+4 t=13 type.string+0
138 rel 356+4 t=6 runtime.convT2E+0
139 rel 390+4 t=13 runtime.writeBarrier+-1
140 rel 431+4 t=6 fmt.Println+0
141 rel 454+4 t=6 runtime.writebarrierptr+0
142 rel 468+4 t=6 runtime.morestack_noctxt+0
143 "".main t=1 size=64 value=0 args=0x0 locals=0x20
144 0x0000 00000 (a1.go:15) TEXT "".main(SB), $32-0 // 32字节局部空间
145 0x0000 00000 (a1.go:15) MOVQ (TLS), CX // 获取TLS
146 0x0009 00009 (a1.go:15) CMPQ SP, 16(CX) // 比较栈指针,扩容。
147 0x000d 00013 (a1.go:15) JLS 57
148 0x000f 00015 (a1.go:15) SUBQ $32, SP // 分配32字节
149 0x0013 00019 (a1.go:16) MOVQ $0, CX // CX = 0
150 0x0015 00021 (a1.go:17) LEAQ type.*int(SB), BX
151 0x001c 00028 (a1.go:17) MOVQ BX, "".autotmp_0013+16(SP) // 16(SP) = & type.*int
152 0x0021 00033 (a1.go:17) MOVQ BX, (SP) // (SP) = & type.*int
153 0x0025 00037 (a1.go:17) MOVQ CX, "".autotmp_0013+24(SP) // 24(SP) = 0
154 0x002a 00042 (a1.go:17) MOVQ CX, 8(SP) // 8(SP) = 0
// arg1 0
// arg0 & type.*int
155 0x002f 00047 (a1.go:17) CALL "".Foo(SB)
156 0x0034 00052 (a1.go:17) NOP
157 0x0034 00052 (a1.go:18) ADDQ $32, SP
158 0x0038 00056 (a1.go:18) RET
159 0x0039 00057 (a1.go:18) NOP
160 0x0039 00057 (a1.go:15) CALL runtime.morestack_noctxt(SB)
161 0x003e 00062 (a1.go:15) JMP 0
162 0x0000 64 48 8b 0c 25 00 00 00 00 48 3b 61 10 76 2a 48 dH..%....H;a.v*H
163 0x0010 83 ec 20 31 c9 48 8d 1d 00 00 00 00 48 89 5c 24 .. 1.H......H.\$
164 0x0020 10 48 89 1c 24 48 89 4c 24 18 48 89 4c 24 08 e8 .H..$H.L$.H.L$..
165 0x0030 00 00 00 00 48 83 c4 20 c3 e8 00 00 00 00 eb c0 ....H.. ........
166 rel 5+4 t=14 +0
167 rel 24+4 t=13 type.*int+0
168 rel 48+4 t=6 "".Foo+0
169 rel 58+4 t=6 runtime.morestack_noctxt+0
Example2
a2.go
package main
import (
"fmt"
)
type MyInterface interface {
Print()
}
type MyStruct struct {}
func (ms MyStruct) Print() {}
func main() {
x := 1
var y interface{} = x
var s MyStruct
var t MyInterface = s
fmt.Println(y, t)
}
go build -gcflags '-l' -o a2 a2.go
go tool objdump -s "main\.main" a2
TEXT main.main(SB) /root/gpkgs/main_interface/a2.go
a2.go:15 0x401010 64488b0c25f8ffffff FS MOVQ FS:0xfffffff8, CX
a2.go:15 0x401019 488d4424d8 LEAQ -0x28(SP), AX
a2.go:15 0x40101e 483b4110 CMPQ 0x10(CX), AX
a2.go:15 0x401022 0f86ab010000 JBE 0x4011d3
a2.go:15 0x401028 4881eca8000000 SUBQ $0xa8, SP
//code 1: x := 1
a2.go:16 0x40102f 48c7c001000000 MOVQ $0x1, AX // 0x38(SP) = 1
a2.go:17 0x401036 4889442438 MOVQ AX, 0x38(SP)
//code 2: var y interface{} = x
a2.go:17 0x40103b 488d1d9e740b00 LEAQ 0xb749e(IP), BX
a2.go:17 0x401042 48891c24 MOVQ BX, 0(SP) // 0(SP) = 0xb749e(IP)
a2.go:17 0x401046 488d5c2438 LEAQ 0x38(SP), BX
a2.go:17 0x40104b 48895c2408 MOVQ BX, 0x8(SP) // 0x08(SP) = & x
a2.go:17 0x401050 48c744241000000000 MOVQ $0x0, 0x10(SP) // 0x10(SP) = 0
a2.go:17 0x401059 e822ab0000 CALL runtime.convT2E(SB)
// 调用runtime.convT2E去创建Emtpy interface的数据结构,参数1 t *_type, 参数2 elem unsafe.Pointer, 返回一个eface结构
// type eface interface{
// _type unsafe.Pointer //
// data unsafe.Pointer //
// }
a2.go:17 0x40105e 488b5c2418 MOVQ 0x18(SP), BX
a2.go:17 0x401063 48895c2440 MOVQ BX, 0x40(SP) // 0x40(SP) = 0x18(SP)
a2.go:17 0x401068 488b5c2420 MOVQ 0x20(SP), BX
a2.go:17 0x40106d 48895c2448 MOVQ BX, 0x48(SP) // 0x48(SP) = 0x20(SP)
a2.go:18 0x401072 31db XORL BX, BX
a2.go:19 0x401074 488d1d45a00d00 LEAQ 0xda045(IP), BX
a2.go:19 0x40107b 48891c24 MOVQ BX, 0(SP)
a2.go:19 0x40107f 488d1dda580d00 LEAQ 0xd58da(IP), BX
a2.go:19 0x401086 48895c2408 MOVQ BX, 0x8(SP)
a2.go:19 0x40108b 488d1de6ea1900 LEAQ 0x19eae6(IP), BX
a2.go:19 0x401092 48895c2410 MOVQ BX, 0x10(SP)
a2.go:19 0x401097 488d5c2438 LEAQ 0x38(SP), BX
a2.go:19 0x40109c 48895c2418 MOVQ BX, 0x18(SP)
a2.go:19 0x4010a1 48c744242000000000 MOVQ $0x0, 0x20(SP)
a2.go:19 0x4010aa e8b1ab0000 CALL runtime.convT2I(SB)
a2.go:19 0x4010af 488b5c2428 MOVQ 0x28(SP), BX
a2.go:19 0x4010b4 48895c2450 MOVQ BX, 0x50(SP)
a2.go:19 0x4010b9 488b5c2430 MOVQ 0x30(SP), BX
a2.go:19 0x4010be 48895c2458 MOVQ BX, 0x58(SP)
a2.go:20 0x4010c3 31c0 XORL AX, AX
a2.go:20 0x4010c5 4889842488000000 MOVQ AX, 0x88(SP)
a2.go:20 0x4010cd 4889842490000000 MOVQ AX, 0x90(SP)
a2.go:20 0x4010d5 4889842498000000 MOVQ AX, 0x98(SP)
a2.go:20 0x4010dd 48898424a0000000 MOVQ AX, 0xa0(SP)
a2.go:20 0x4010e5 488d842488000000 LEAQ 0x88(SP), AX
a2.go:20 0x4010ed 4883f800 CMPQ $0x0, AX
a2.go:20 0x4010f1 0f84d5000000 JE 0x4011cc
a2.go:20 0x4010f7 48c744247802000000 MOVQ $0x2, 0x78(SP)
a2.go:20 0x401100 48c784248000000002000000 MOVQ $0x2, 0x80(SP)
a2.go:20 0x40110c 4889442470 MOVQ AX, 0x70(SP)
a2.go:20 0x401111 488b6c2440 MOVQ 0x40(SP), BP
a2.go:20 0x401116 488928 MOVQ BP, 0(AX)
a2.go:20 0x401119 488b6c2448 MOVQ 0x48(SP), BP
a2.go:20 0x40111e 803dbbe9190000 CMPL $0x0, 0x19e9bb(IP)
a2.go:20 0x401125 0f858a000000 JNE 0x4011b5
a2.go:20 0x40112b 48896808 MOVQ BP, 0x8(AX)
a2.go:20 0x40112f 488b5c2450 MOVQ 0x50(SP), BX
a2.go:20 0x401134 48891c24 MOVQ BX, 0(SP)
a2.go:20 0x401138 488b5c2458 MOVQ 0x58(SP), BX
a2.go:20 0x40113d 48895c2408 MOVQ BX, 0x8(SP)
a2.go:20 0x401142 e869b10000 CALL runtime.convI2E(SB)
a2.go:20 0x401147 488b4c2410 MOVQ 0x10(SP), CX
a2.go:20 0x40114c 488b442418 MOVQ 0x18(SP), AX
a2.go:20 0x401151 488b5c2470 MOVQ 0x70(SP), BX
a2.go:20 0x401156 4883c310 ADDQ $0x10, BX
a2.go:20 0x40115a 48894c2460 MOVQ CX, 0x60(SP)
a2.go:20 0x40115f 48890b MOVQ CX, 0(BX)
a2.go:20 0x401162 4889442468 MOVQ AX, 0x68(SP)
a2.go:20 0x401167 803d72e9190000 CMPL $0x0, 0x19e972(IP)
a2.go:20 0x40116e 7531 JNE 0x4011a1
a2.go:20 0x401170 48894308 MOVQ AX, 0x8(BX)
a2.go:20 0x401174 488b5c2470 MOVQ 0x70(SP), BX
a2.go:20 0x401179 48891c24 MOVQ BX, 0(SP)
a2.go:20 0x40117d 488b5c2478 MOVQ 0x78(SP), BX
a2.go:20 0x401182 48895c2408 MOVQ BX, 0x8(SP)
a2.go:20 0x401187 488b9c2480000000 MOVQ 0x80(SP), BX
a2.go:20 0x40118f 48895c2410 MOVQ BX, 0x10(SP)
a2.go:20 0x401194 e8b7960500 CALL fmt.Println(SB)
a2.go:21 0x401199 4881c4a8000000 ADDQ $0xa8, SP
a2.go:21 0x4011a0 c3 RET
a2.go:20 0x4011a1 4c8d4308 LEAQ 0x8(BX), R8
a2.go:20 0x4011a5 4c890424 MOVQ R8, 0(SP)
a2.go:20 0x4011a9 4889442408 MOVQ AX, 0x8(SP)
a2.go:20 0x4011ae e8cdde0000 CALL runtime.writebarrierptr(SB)
a2.go:20 0x4011b3 ebbf JMP 0x401174
a2.go:20 0x4011b5 4c8d4008 LEAQ 0x8(AX), R8
a2.go:20 0x4011b9 4c890424 MOVQ R8, 0(SP)
a2.go:20 0x4011bd 48896c2408 MOVQ BP, 0x8(SP)
a2.go:20 0x4011c2 e8b9de0000 CALL runtime.writebarrierptr(SB)
a2.go:20 0x4011c7 e963ffffff JMP 0x40112f
a2.go:20 0x4011cc 8900 MOVL AX, 0(AX)
a2.go:20 0x4011ce e924ffffff JMP 0x4010f7
a2.go:15 0x4011d3 e8e8210500 CALL runtime.morestack_noctxt(SB)
a2.go:15 0x4011d8 e933feffff JMP main.main(SB)
a2.go:15 0x4011dd cc INT $0x3
a2.go:15 0x4011de cc INT $0x3
a2.go:15 0x4011df cc INT $0x3
func convT2E(t *_type, elem unsafe.Pointer) (e eface) {
if raceenabled {
raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2E))
}
if msanenabled {
msanread(elem, t.size)
}
if isDirectIface(t) {
// This case is implemented directly by the compiler.
throw("direct convT2E")
}
x := newobject(t) // 新建一个对象
// TODO: We allocate a zeroed object only to overwrite it with
// actual data. Figure out how to avoid zeroing. Also below in convT2I.
typedmemmove(t, x, elem)
e._type = t //类型赋值
e.data = x //数据赋值
return
}
3、
eface结构
// src/runtime/runtime2.go
// 空接口
type eface struct {
_type *_type
data unsafe.Pointer
}
_type
结构
// 所有类型信息结构体的公共部分
// src/rumtime/runtime2.go
type _type struct {
size uintptr // 类型的大小
ptrdata uintptr // size of memory prefix holding all pointers
hash uint32 // 类型的Hash值
tflag tflag // 类型的Tags
align uint8 // 结构体内对齐
fieldalign uint8 // 结构体作为field时的对齐
kind uint8 // 类型编号 定义于runtime/typekind.go
alg *typeAlg // 类型元方法 存储hash和equal两个操作。map key便使用key的_type.alg.hash(k)获取hash值
gcdata *byte // GC相关信息
str nameOff // 类型名字的偏移
ptrToThis typeOff
}
iface表示空接口
// runtime/runtime2.go
// 非空接口
type iface struct {
tab *itab
data unsafe.Pointer
}
// 非空接口的类型信息
type itab struct {
inter *interfacetype // 接口定义的类型信息
_type *_type // 接口实际指向值的类型信息
link *itab
bad int32
inhash int32
fun [1]uintptr // 接口方法实现列表,即函数地址列表,按字典序排序
}
// runtime/type.go
// 非空接口类型,接口定义,包路径等。
type interfacetype struct {
typ _type
pkgpath name
mhdr []imethod // 接口方法声明列表,按字典序排序
}
// 接口的方法声明
type imethod struct {
name nameOff // 方法名
ityp typeOff // 描述方法参数返回值等细节
}
非空接口(iface)本身除了可以容纳满足其接口的对象之外,还需要保存其接口的方法,因此除了data字段描述数据外,tab字段用于描述接口的细节,包括接口方法定义,接口方法实现的地址,接口所指的类型。iface是非空接口的实现,而不是类型的定义。iface真正类型为iface.interfacetype. 其第一个字段仍然为描述其自身类型的_type字段。
package main
import (
"fmt"
)
type MyInterface interface {
Print()
}
type MyStruct struct {}
func (ms MyStruct) Print() {}
func main() {
a := 1
b := "str"
c := MyStruct{}
var i1 interface{} = a
var i2 interface{} = b
var i3 MyInterface = c
var i4 interface{} = i3
var i5 = i4.(MyInterface)
fmt.Println(i1, i2, i3, i4, i5)
}
1 TEXT main.main(SB) /root/gpkgs/main_interface/a3.go
2 a3.go:14 0x401010 64488b0c25f8ffffff FS MOVQ FS:0xfffffff8, CX
3 a3.go:14 0x401019 488d842428ffffff LEAQ 0xffffff28(SP), AX
4 a3.go:14 0x401021 483b4110 CMPQ 0x10(CX), AX
5 a3.go:14 0x401025 0f86ec030000 JBE 0x401417
6 a3.go:14 0x40102b 4881ec58010000 SUBQ $0x158, SP
// a := 1
7 a3.go:15 0x401032 48c744244001000000 MOVQ $0x1, 0x40(SP) // 0x40(SP) = 1
// b := "str"
8 a3.go:16 0x40103b 488d1dced20f00 LEAQ 0xfd2ce(IP), BX
9 a3.go:16 0x401042 48899c24a0000000 MOVQ BX, 0xa0(SP) // 0xa0 字符串地址
10 a3.go:16 0x40104a 48c78424a800000003000000 MOVQ $0x3, 0xa8(SP) // 0xa8 字符串长度
11 a3.go:17 0x401056 31db XORL BX, BX
// var i1 interface{} = a
12 a3.go:19 0x401058 488b5c2440 MOVQ 0x40(SP), BX
13 a3.go:19 0x40105d 48895c2438 MOVQ BX, 0x38(SP)
14 a3.go:19 0x401062 488d1d77740b00 LEAQ 0xb7477(IP), BX // 加载a的类型信息到0(SP)
15 a3.go:19 0x401069 48891c24 MOVQ BX, 0(SP)
16 a3.go:19 0x40106d 488d5c2438 LEAQ 0x38(SP), BX // 加载a的地址到8(SP)
17 a3.go:19 0x401072 48895c2408 MOVQ BX, 0x8(SP)
18 a3.go:19 0x401077 48c744241000000000 MOVQ $0x0, 0x10(SP) // 0x10(SP) = 0
19 a3.go:19 0x401080 e8cbad0000 CALL runtime.convT2E(SB)
20 a3.go:19 0x401085 488b5c2418 MOVQ 0x18(SP), BX
21 a3.go:19 0x40108a 48899c2490000000 MOVQ BX, 0x90(SP) // _type *_type
22 a3.go:19 0x401092 488b5c2420 MOVQ 0x20(SP), BX
23 a3.go:19 0x401097 48899c2498000000 MOVQ BX, 0x98(SP) // data unsafe.Pointer
// var i2 interface{} := b
24 a3.go:20 0x40109f 488b9c24a0000000 MOVQ 0xa0(SP), BX
25 a3.go:20 0x4010a7 48899c24e0000000 MOVQ BX, 0xe0(SP) // 0xe0 = & "str"
26 a3.go:20 0x4010af 488b9c24a8000000 MOVQ 0xa8(SP), BX
27 a3.go:20 0x4010b7 48899c24e8000000 MOVQ BX, 0xe8(SP) // len = 3
28 a3.go:20 0x4010bf 488d1d9a7d0b00 LEAQ 0xb7d9a(IP), BX
29 a3.go:20 0x4010c6 48891c24 MOVQ BX, 0(SP) // 类型
30 a3.go:20 0x4010ca 488d9c24e0000000 LEAQ 0xe0(SP), BX
31 a3.go:20 0x4010d2 48895c2408 MOVQ BX, 0x8(SP) // 地址
32 a3.go:20 0x4010d7 48c744241000000000 MOVQ $0x0, 0x10(SP)
33 a3.go:20 0x4010e0 e86bad0000 CALL runtime.convT2E(SB) // 创建interface,eface
34 a3.go:20 0x4010e5 488b5c2418 MOVQ 0x18(SP), BX
35 a3.go:20 0x4010ea 48899c2480000000 MOVQ BX, 0x80(SP) // i2._type
36 a3.go:20 0x4010f2 488b5c2420 MOVQ 0x20(SP), BX
37 a3.go:20 0x4010f7 48899c2488000000 MOVQ BX, 0x88(SP) // i2.data
// var i3 MyInterface = c
38 a3.go:21 0x4010ff 488d1dba9f0d00 LEAQ 0xd9fba(IP), BX
39 a3.go:21 0x401106 48891c24 MOVQ BX, 0(SP) // arg0 =
40 a3.go:21 0x40110a 488d1d4f580d00 LEAQ 0xd584f(IP), BX
41 a3.go:21 0x401111 48895c2408 MOVQ BX, 0x8(SP)// arg1 =
42 a3.go:21 0x401116 488d1d5bea1900 LEAQ 0x19ea5b(IP), BX
43 a3.go:21 0x40111d 48895c2410 MOVQ BX, 0x10(SP)// =
44 a3.go:21 0x401122 488d5c2438 LEAQ 0x38(SP), BX
45 a3.go:21 0x401127 48895c2418 MOVQ BX, 0x18(SP)// 0x18(SP) = &a
46 a3.go:21 0x40112c 48c744242000000000 MOVQ $0x0, 0x20(SP)
47 a3.go:21 0x401135 e8f6ad0000 CALL runtime.convT2I(SB) // 为什么入参是32字节
48 a3.go:21 0x40113a 488b5c2428 MOVQ 0x28(SP), BX
49 a3.go:21 0x40113f 48895c2470 MOVQ BX, 0x70(SP) // i3.tab
50 a3.go:21 0x401144 488b5c2430 MOVQ 0x30(SP), BX
51 a3.go:21 0x401149 48895c2478 MOVQ BX, 0x78(SP) // i3.data
52 a3.go:22 0x40114e 488b5c2470 MOVQ 0x70(SP), BX
53 a3.go:22 0x401153 48891c24 MOVQ BX, 0(SP)
54 a3.go:22 0x401157 488b5c2478 MOVQ 0x78(SP), BX
55 a3.go:22 0x40115c 48895c2408 MOVQ BX, 0x8(SP)
56 a3.go:22 0x401161 e81ab40000 CALL runtime.convI2E(SB)
57 a3.go:22 0x401166 488b5c2410 MOVQ 0x10(SP), BX
58 a3.go:22 0x40116b 48895c2460 MOVQ BX, 0x60(SP)
59 a3.go:22 0x401170 488b5c2418 MOVQ 0x18(SP), BX
60 a3.go:22 0x401175 48895c2468 MOVQ BX, 0x68(SP)
61 a3.go:23 0x40117a 31db XORL BX, BX
62 a3.go:23 0x40117c 48899c24d0000000 MOVQ BX, 0xd0(SP)
63 a3.go:23 0x401184 48899c24d8000000 MOVQ BX, 0xd8(SP)
64 a3.go:23 0x40118c 488d1dcd570d00 LEAQ 0xd57cd(IP), BX
65 a3.go:23 0x401193 48891c24 MOVQ BX, 0(SP)
66 a3.go:23 0x401197 488b5c2460 MOVQ 0x60(SP), BX
67 a3.go:23 0x40119c 48895c2408 MOVQ BX, 0x8(SP)
68 a3.go:23 0x4011a1 488b5c2468 MOVQ 0x68(SP), BX
69 a3.go:23 0x4011a6 48895c2410 MOVQ BX, 0x10(SP)
70 a3.go:23 0x4011ab 488d9c24d0000000 LEAQ 0xd0(SP), BX
71 a3.go:23 0x4011b3 48895c2418 MOVQ BX, 0x18(SP)
72 a3.go:23 0x4011b8 e8f3b30000 CALL runtime.assertE2I(SB)
73 a3.go:23 0x4011bd 488b9c24d0000000 MOVQ 0xd0(SP), BX
74 a3.go:23 0x4011c5 48895c2450 MOVQ BX, 0x50(SP)
75 a3.go:23 0x4011ca 488b9c24d8000000 MOVQ 0xd8(SP), BX
76 a3.go:23 0x4011d2 48895c2458 MOVQ BX, 0x58(SP)
77 a3.go:25 0x4011d7 488dbc2408010000 LEAQ 0x108(SP), DI
78 a3.go:25 0x4011df 0f57c0 XORPS X0, X0
79 a3.go:25 0x4011e2 4883c7d0 ADDQ $-0x30, DI
80 a3.go:25 0x4011e6 e87a4b0500 CALL 0x455d65
81 a3.go:25 0x4011eb 488d9c2408010000 LEAQ 0x108(SP), BX
82 a3.go:25 0x4011f3 48895c2448 MOVQ BX, 0x48(SP)
83 a3.go:25 0x4011f8 488b5c2448 MOVQ 0x48(SP), BX
84 a3.go:25 0x4011fd 4883fb00 CMPQ $0x0, BX
85 a3.go:25 0x401201 0f8409020000 JE 0x401410
86 a3.go:25 0x401207 48c78424f800000005000000 MOVQ $0x5, 0xf8(SP)
87 a3.go:25 0x401213 48c784240001000005000000 MOVQ $0x5, 0x100(SP)
88 a3.go:25 0x40121f 48899c24f0000000 MOVQ BX, 0xf0(SP)
89 a3.go:25 0x401227 488b9c24f0000000 MOVQ 0xf0(SP), BX
90 a3.go:25 0x40122f 488bac2490000000 MOVQ 0x90(SP), BP
91 a3.go:25 0x401237 48892b MOVQ BP, 0(BX)
92 a3.go:25 0x40123a 488bac2498000000 MOVQ 0x98(SP), BP
93 a3.go:25 0x401242 803d97e8190000 CMPL $0x0, 0x19e897(IP)
94 a3.go:25 0x401249 0f85aa010000 JNE 0x4013f9
95 a3.go:25 0x40124f 48896b08 MOVQ BP, 0x8(BX)
96 a3.go:25 0x401253 488b9c24f0000000 MOVQ 0xf0(SP), BX
97 a3.go:25 0x40125b 4883c310 ADDQ $0x10, BX
98 a3.go:25 0x40125f 488bac2480000000 MOVQ 0x80(SP), BP
99 a3.go:25 0x401267 48892b MOVQ BP, 0(BX)
100 a3.go:25 0x40126a 488bac2488000000 MOVQ 0x88(SP), BP
101 a3.go:25 0x401272 803d67e8190000 CMPL $0x0, 0x19e867(IP)
102 a3.go:25 0x401279 0f8563010000 JNE 0x4013e2
103 a3.go:25 0x40127f 48896b08 MOVQ BP, 0x8(BX)
104 a3.go:25 0x401283 488b5c2470 MOVQ 0x70(SP), BX
105 a3.go:25 0x401288 48891c24 MOVQ BX, 0(SP)
106 a3.go:25 0x40128c 488b5c2478 MOVQ 0x78(SP), BX
107 a3.go:25 0x401291 48895c2408 MOVQ BX, 0x8(SP)
108 a3.go:25 0x401296 e8e5b20000 CALL runtime.convI2E(SB)
109 a3.go:25 0x40129b 488b5c2410 MOVQ 0x10(SP), BX
110 a3.go:25 0x4012a0 48899c24c0000000 MOVQ BX, 0xc0(SP)
111 a3.go:25 0x4012a8 488b5c2418 MOVQ 0x18(SP), BX
112 a3.go:25 0x4012ad 48899c24c8000000 MOVQ BX, 0xc8(SP)
113 a3.go:25 0x4012b5 488b9c24f0000000 MOVQ 0xf0(SP), BX
114 a3.go:25 0x4012bd 4883c320 ADDQ $0x20, BX
115 a3.go:25 0x4012c1 488bac24c0000000 MOVQ 0xc0(SP), BP
116 a3.go:25 0x4012c9 48892b MOVQ BP, 0(BX)
117 a3.go:25 0x4012cc 488bac24c8000000 MOVQ 0xc8(SP), BP
118 a3.go:25 0x4012d4 803d05e8190000 CMPL $0x0, 0x19e805(IP)
119 a3.go:25 0x4012db 0f85ea000000 JNE 0x4013cb
120 a3.go:25 0x4012e1 48896b08 MOVQ BP, 0x8(BX)
121 a3.go:25 0x4012e5 488b9c24f0000000 MOVQ 0xf0(SP), BX
122 a3.go:25 0x4012ed 4883c330 ADDQ $0x30, BX
123 a3.go:25 0x4012f1 488b6c2460 MOVQ 0x60(SP), BP
124 a3.go:25 0x4012f6 48892b MOVQ BP, 0(BX)
125 a3.go:25 0x4012f9 488b6c2468 MOVQ 0x68(SP), BP
126 a3.go:25 0x4012fe 803ddbe7190000 CMPL $0x0, 0x19e7db(IP)
127 a3.go:25 0x401305 0f85a9000000 JNE 0x4013b4
128 a3.go:25 0x40130b 48896b08 MOVQ BP, 0x8(BX)
129 a3.go:25 0x40130f 488b5c2450 MOVQ 0x50(SP), BX
130 a3.go:25 0x401314 48891c24 MOVQ BX, 0(SP)
131 a3.go:25 0x401318 488b5c2458 MOVQ 0x58(SP), BX
132 a3.go:25 0x40131d 48895c2408 MOVQ BX, 0x8(SP)
133 a3.go:25 0x401322 e859b20000 CALL runtime.convI2E(SB)
134 a3.go:25 0x401327 488b5c2410 MOVQ 0x10(SP), BX
135 a3.go:25 0x40132c 48899c24b0000000 MOVQ BX, 0xb0(SP)
136 a3.go:25 0x401334 488b5c2418 MOVQ 0x18(SP), BX
137 a3.go:25 0x401339 48899c24b8000000 MOVQ BX, 0xb8(SP)
138 a3.go:25 0x401341 488b9c24f0000000 MOVQ 0xf0(SP), BX
139 a3.go:25 0x401349 4883c340 ADDQ $0x40, BX
140 a3.go:25 0x40134d 488bac24b0000000 MOVQ 0xb0(SP), BP
141 a3.go:25 0x401355 48892b MOVQ BP, 0(BX)
142 a3.go:25 0x401358 488bac24b8000000 MOVQ 0xb8(SP), BP
143 a3.go:25 0x401360 803d79e7190000 CMPL $0x0, 0x19e779(IP)
144 a3.go:25 0x401367 7537 JNE 0x4013a0
145 a3.go:25 0x401369 48896b08 MOVQ BP, 0x8(BX)
146 a3.go:25 0x40136d 488b9c24f0000000 MOVQ 0xf0(SP), BX
147 a3.go:25 0x401375 48891c24 MOVQ BX, 0(SP)
148 a3.go:25 0x401379 488b9c24f8000000 MOVQ 0xf8(SP), BX
149 a3.go:25 0x401381 48895c2408 MOVQ BX, 0x8(SP)
150 a3.go:25 0x401386 488b9c2400010000 MOVQ 0x100(SP), BX
151 a3.go:25 0x40138e 48895c2410 MOVQ BX, 0x10(SP)
152 a3.go:25 0x401393 e888970500 CALL fmt.Println(SB)
153 a3.go:26 0x401398 4881c458010000 ADDQ $0x158, SP
154 a3.go:26 0x40139f c3 RET
155 a3.go:25 0x4013a0 4c8d4308 LEAQ 0x8(BX), R8
156 a3.go:25 0x4013a4 4c890424 MOVQ R8, 0(SP)
157 a3.go:25 0x4013a8 48896c2408 MOVQ BP, 0x8(SP)
158 a3.go:25 0x4013ad e89edf0000 CALL runtime.writebarrierptr(SB)
159 a3.go:25 0x4013b2 ebb9 JMP 0x40136d
160 a3.go:25 0x4013b4 4c8d4308 LEAQ 0x8(BX), R8
161 a3.go:25 0x4013b8 4c890424 MOVQ R8, 0(SP)
162 a3.go:25 0x4013bc 48896c2408 MOVQ BP, 0x8(SP)
163 a3.go:25 0x4013c1 e88adf0000 CALL runtime.writebarrierptr(SB)
164 a3.go:25 0x4013c6 e944ffffff JMP 0x40130f
165 a3.go:25 0x4013cb 4c8d4308 LEAQ 0x8(BX), R8
166 a3.go:25 0x4013cf 4c890424 MOVQ R8, 0(SP)
167 a3.go:25 0x4013d3 48896c2408 MOVQ BP, 0x8(SP)
168 a3.go:25 0x4013d8 e873df0000 CALL runtime.writebarrierptr(SB)
169 a3.go:25 0x4013dd e903ffffff JMP 0x4012e5
170 a3.go:25 0x4013e2 4c8d4308 LEAQ 0x8(BX), R8
171 a3.go:25 0x4013e6 4c890424 MOVQ R8, 0(SP)
172 a3.go:25 0x4013ea 48896c2408 MOVQ BP, 0x8(SP)
173 a3.go:25 0x4013ef e85cdf0000 CALL runtime.writebarrierptr(SB)
174 a3.go:25 0x4013f4 e98afeffff JMP 0x401283
175 a3.go:25 0x4013f9 4c8d4308 LEAQ 0x8(BX), R8
176 a3.go:25 0x4013fd 4c890424 MOVQ R8, 0(SP)
177 a3.go:25 0x401401 48896c2408 MOVQ BP, 0x8(SP)
178 a3.go:25 0x401406 e845df0000 CALL runtime.writebarrierptr(SB)
179 a3.go:25 0x40140b e943feffff JMP 0x401253
180 a3.go:25 0x401410 8903 MOVL AX, 0(BX)
181 a3.go:25 0x401412 e9f0fdffff JMP 0x401207
182 a3.go:14 0x401417 e874220500 CALL runtime.morestack_noctxt(SB)
183 a3.go:14 0x40141c e9effbffff JMP main.main(SB)
func convT2E(t *_type, elem unsafe.Pointer) (e eface) {
...
x := newobject(t)
typedmemmove(t, x, elem)
e._type = t
e.data = x
return
}
func convT2I(tab *itab, elem unsafe.Pointer) (i iface) {
t := tab._type
...
x := newobject(t)
typedmemmove(t, x, elem)
i.tab = tab
i.data = x
return
}