敦煌 |玉门 |瓜州 |金塔 |甘肃 |互联网 |教育 |社会 |

实时·准确·聚焦

当前位置:社会资讯 > 互联网> 两万字深入解密Go语言接口的那些事儿|技术头条

两万字深入解密Go语言接口的那些事儿|技术头条

2019-05-04 13:53 | CSDN |

原标题:两万字深入解密 Go 语言接口的那些事儿 | 技术头条

Go 语言的接口的原理是什么?是如何使用?它和C++接口有什么异同呢?本文作者用两万多字深入一一为你讲述Go语言interface的那些事儿。


两万字深入解密Go语言接口的那些事儿|技术头条

:

coder.say_hello()

IGreeting {

sayHello()

}

{

i.sayHello()

}

Go {} { fmt.Println( )} PHP {} { fmt.Println( )}

{ golang := Go{} php := PHP{} sayHello(golang) sayHello(php)}

Hi, I am GO!Hi, I am PHP!

main

Person {

age

}

{

p.age

}

{

p.age +=

}

{

qcrao := Person{age: }

fmt.Println(qcrao.howOld())

qcrao.growUp()

fmt.Println(qcrao.howOld())

stefno := &Person{age: }

fmt.Println(stefno.howOld())

stefno.growUp()

fmt.Println(stefno.howOld())

}

18

19

100

101

main

coder {

code()

debug()

}

Gopher {

language

}

{

fmt.Printf(, p.language)

}

{

fmt.Printf(, p.language)

}

{

c coder = &Gopher{}

c.code()

c.debug()

}

am coding Go language

I am debuging Go language

{

c coder = Gopher{}

c.code()

c.debug()

}

./main.go:24:6: cannot Programmer literal (Programmer) coder assignment: Programmer does implement coder (debug method has pointer receiver)

iface {

tab *itab

data unsafe.Pointer

}

itab {

inter *interfacetype

_type *_type

link *itab

hash

bad

inhash

unused []

fun []

}

type interfacetype {

typ _type

pkgpath name

mhdr []imethod

}


两万字深入解密Go语言接口的那些事儿|技术头条

type eface {_type *_type data unsafe.Pointer}


两万字深入解密Go语言接口的那些事儿|技术头条

main

{

x :=

any {} = x

fmt.Println(any)

g := Gopher{}

c coder = g

fmt.Println(c)

}

coder {

code()

debug()

}

Gopher {

language

}

{

fmt.Printf(, p.language)

}

{

fmt.Printf(, p.language)

}

tool compile -S ./src/main.

_type {

size

ptrdata

hash

tflag tflag

align

fieldalign

kind

alg *typeAlg

gcdata *

str nameOff

ptrToThis typeOff

}

arraytype {

typ _type

elem *_type

slice *_type

}

chantype {

typ _type

elem *_type

dir

}

slicetype {

typ _type

elem *_type

}

structtype {

typ _type

pkgPath name

fields []structfield

}

main

Coder {

code()

}

Gopher {

name

}

{

fmt.Printf(, g.name)

}

{

c Coder

fmt.Println(c == )

fmt.Printf(, c, c)

g *Gopher

fmt.Println(g == )

c = g

fmt.Println(c == )

fmt.Printf(, c, c)

}

true

c: >, >

true

false

c: *main.Gopher, >

main

MyError {}

{

}

{

err := Process()

fmt.Println(err)

fmt.Println(err == )

}

{

err *MyError =

err

}

< >

main

(

)

iface {

itab, data

}

{

a {} =

b {} = (*)()

x :=

c {} = (*)(&x)

ia := *(*iface)(unsafe.Pointer(&a))

ib := *(*iface)(unsafe.Pointer(&b))

ic := *(*iface)(unsafe.Pointer(&c))

fmt.Println(ia, ib, ic)

fmt.Println(*(*)(unsafe.Pointer(ic.data)))

}

{0 0} {17426912 0} {17426912 842350714568}

5

var _ .Writer = (*myWriter)()

main

myWriter {

}

return

}*/

{

_ io.Writer = (*myWriter)()

_ io.Writer = myWriter{}

}

src/main.go:14:6: cannot (*myWriter)(nil) (*myWriter) io.Writer assignment:

*myWriter does implement io.Writer (Write method)

src/main.go::: cannot myWriter literal (myWriter) io.Writer assignment:

myWriter does implement io.Writer (Write method)

var _ .Writer = (*myWriter)( )var _ .Writer = myWriter{}

main

Person {

growUp()

}

Student {

age

}

{

p.age +=

}

{

qcrao = Person(Student{age: })

fmt.Println(qcrao)

}

tool compile -S ./src/main.

(./src/main.:) TEXT .main(SB), $

(./src/main.:) MOVQ (TLS), CX

(./src/main.:) CMPQ SP, (CX)

(./src/main.:) JLS

(./src/main.:) SUBQ $, SP

(./src/main.:) MOVQ BP, (SP)

(./src/main.:) LEAQ (SP), BP

(./src/main.:) FUNCDATA$, gclocals·c1753bd5f81501d95132d08af04464(SB)

(./src/main.:) FUNCDATA$, gclocals·e226d4ae4a7cad8835311c6a4683c14f(SB)

(./src/main.:) MOVQ $, ..autotmp_1+(SP)

(./src/main.:) LEAQ .itab..Student,.Person(SB), AX

(./src/main.:) MOVQ AX, (SP)

(./src/main.:) LEAQ ..autotmp_1+(SP), AX

(./src/main.:) MOVQ AX, (SP)

(./src/main.:) PCDATA $, $

(./src/main.:) CALL runtime.convT2I64(SB)

(./src/main.:) MOVQ (SP), AX

(./src/main.:) MOVQ (SP), CX

(./src/main.:) TESTQ CX, CX

(./src/main.:) JEQ

(./src/main.:) MOVQ (CX), CX

(./src/main.:) MOVQ $, ..autotmp_2+(SP)

(./src/main.:) MOVQ $, ..autotmp_2+(SP)

(./src/main.:) MOVQ CX, ..autotmp_2+(SP)

(./src/main.:) MOVQ AX, ..autotmp_2+(SP)

(./src/main.:) LEAQ ..autotmp_2+(SP), AX

(./src/main.:) MOVQ AX, (SP)

(./src/main.:) MOVQ $, (SP)

(./src/main.:) MOVQ $, (SP)

(./src/main.:) PCDATA $, $

(./src/main.:) CALL fmt.Println(SB)

(./src/main.:) MOVQ (SP), BP

(./src/main.:) ADDQ $, SP

(./src/main.:) RET

(./src/main.:) NOP

(./src/main.:) PCDATA $, $

(./src/main.:) CALL runtime.morestack_noctxt(SB)

(./src/main.:) JMP

{

.itab..Student,.Person SNOPTRDATA dupok size=

da d4

rel +t=..Person+

rel +t=..Student+

itab {

inter *interfacetype

_type *_type

link *itab

hash

bad

inhash

unused []

fun []

}

{

t := tab._type

x unsafe.Pointer

*(*)(elem) == {

x = unsafe.Pointer(&zeroVal[])

} {

x = mallocgc(, t, )

*(*)(x) = *(*)(elem)

}

i.tab = tab

i.data = http://www.sohu.com/a/x

}

iface {

tab *itab

data unsafe.Pointer

}

itab {

inter

_type

link

hash

_ []

fun []

}

{

qcrao = Person(Student{age: })

iface := (*iface)(unsafe.Pointer(&qcrao))

fmt.Printf(, iface.tab.hash)

}

iface.tab.hash = a

main

{

i =

f

f = (i)

fmt.Printf(, f, f)

f =

a := (f)

fmt.Printf(, a, a)

cannot convert i () to []

main

Student {

Name

Age

}

{

i {} = (Student)

s := i.(Student)

fmt.Println(s)

}

panic: conversion: *main.Student, main.Student

{

i {} = (Student)

s, ok := i.(Student)

ok {

fmt.Println(s)

}

}

{

i {}

fmt.Printf(, &i, i)

judge(i)

}

{}){

fmt.Printf(, &v, v)

v := v.() {

:

fmt.Printf(, &v, v)

fmt.Printf(, v, v)

Student:

fmt.Printf(, &v, v)

fmt.Printf(, v, v)

*Student:

fmt.Printf(, &v, v)

fmt.Printf(, v, v)

:

fmt.Printf(, &v, v)

fmt.Printf()

}

}

Student {

Name

Age

}

[Name: ], [Age: ]

0 [Name: ], [Age: ]

[Name: ], [Age: ]

*Student [*main.Student] [Name: ], [Age: ]

0 <>

0 <>

<>

*Student [*main.Student] <>

0 <>

<>

0 <>

[<>] <>

i {} = (Student)

i {} = (*Student)()

i {}

main

Student {

Name

Age

}

{

s = Student{

Name: ,

Age: ,

}

fmt.Println(s)

}

{

fmt.Sprintf(, s.Name, s.Age)

}

,

{

fmt.Sprintf(, s.Name, s.Age)

}

main

coder {

code()

run()

}

runner {

run()

}

Gopher {

language

}

{

}

{

}

{

c coder = Gopher{}

r runner

r = c

fmt.Println(c, r)

}

func convI2I(inter *interfacetype, i iface) (r iface) {

tab := i.tab

tab == nil {

}

tab.inter == inter {

r.tab = tab

r.= i.

}

r.tab = getitab(inter, tab._type, )

r.= i.

}

)*{

h := itabhash(inter, typ)

m *itab

locked

locked = ; locked < ; locked++ {

locked != {

lock(&ifaceLock)

}

m = (*itab)(atomic.Loadp(unsafe.Pointer(&hash[h]))); m != ; m = m.link {

m.inter == inter && m._type == typ {

locked != {

unlock(&ifaceLock)

}

m

}

}

}

m = (*itab)(persistentalloc(unsafe.Sizeof(itab{})+((inter.mhdr))*sys.PtrSize, , &memstats.other_sys))

m.inter = inter

m._type = typ

additab(m, , canfail)

unlock(&ifaceLock)

m.bad {

}

m

}

){

inter := m.inter

typ := m._type

x := typ.uncommon()

ni := (inter.mhdr)

nt := (x.mcount)

xmhdr := (*[<< ]method)(add(unsafe.Pointer(x), (x.moff)))[:nt:nt]

j :=

k := ; k < ni; k++ {

i := &inter.mhdr[k]

itype := inter.typ.typeOff(i.ityp)

name := inter.typ.nameOff(i.name)

iname := name.name()

ipkg := name.pkgPath()

ipkg == {

ipkg = inter.pkgpath.name()

}

; j < nt; j++ {

t := &xmhdr[j]

tname := typ.nameOff(t.name)

typ.typeOff(t.mtyp) == itype && tname.name() == iname {

pkgPath := tname.pkgPath()

pkgPath == {

pkgPath = typ.nameOff(x.pkgpath).name()

}

tname.isExported() || pkgPath == ipkg {

m != {

ifn := typ.textOff(t.ifn)

*(*unsafe.Pointer)(add(unsafe.Pointer(&m.fun[]), (k)*sys.PtrSize)) = ifn

}

nextimethod

}

}

}

m.bad =

nextimethod:

}

!locked {

throw()

}

h := itabhash(inter, typ)

m.link = hash[h]

m.inhash =

atomicstorep(unsafe.Pointer(&hash[h]), unsafe.Pointer(m))

}

{

h := inter.typ.hash

h += * typ.hash

h % hashSize

}

main

{

qcrao := Student{age: }

whatJob(&qcrao)

growUp(&qcrao)

fmt.Println(qcrao)

stefno := Programmer{age: }

whatJob(stefno)

growUp(stefno)

fmt.Println(stefno)

}

{

p.job()

}

{

p.growUp()

}

Person {

job()

growUp()

}

Student {

age

}

{

fmt.Println()

}

{

p.age +=

}

Programmer {

age

}

{

fmt.Println()

}

{

p.age +=

}

I am a student.

{19}

I am a programmer.

{100}

{

:

= ;

:

name;

};

上一篇:
下一篇:
(责任编辑:)
图片推荐
图文资讯