GO语言从入门到放弃-interface-1

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
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值