go interface 类型用法

    xiaoxiao2022-07-03  147

    一个例子短平快的了解 interface 的语法

    接口定义

    接口实现

    接口零值 nil

    表达式实现接口的方法,可以赋值给接口变量

    实例赋值给接口指针赋值给接口接口赋值给接口

    T 型值方法集 (t T)

    *T 型值方法集 (t T) 和 (t *T)

    判等,可赋值,可判等

    类型断言 t = x.(T)

    断言是具体类型断言是接口类型断言失败,崩溃断言空接口值,肯定失败,崩溃断言返回二元组,如果成功返回值 和 true断言返回二元组,如果失败返回 nil 和 false, 而不是崩溃

    类型分支

    例子

    package main import "fmt" //接口定义 type Reader interface { Read() T } // type Writer interface { Write(arg T) } // type ReadWrite interface { Read() T Write(arg T) } // 接口实现 type T int64 func (t T) Read() T { return t } func (t *T) Write(arg T) { *t = arg } func main() { var t T = 123 var r Reader var w Writer var rw ReadWrite var n ReadWrite //接口零值nil fmt.Println(t, r, w, rw, n) //123 <nil> <nil> <nil> <nil> //表达式实现接口的方法,可以赋值给接口变量 r = t //实例赋值给接口 rw = &t //指针赋值给接口 w = rw //接口赋值给接口 // T 型值方法集 (t T) ,这里 Read r = t //w = t //(t *T) 型方法不是 T 型值的方法集 //T(10).Write(t) //(t *T) 型方法不是 T 型值的方法集 <== T(10) 无法取地址,无法调用 Write 方法 // *T 型值方法集 (t T) 和 (t *T), 这里 Read Write r = &t w = &t //判等,可赋值,可判等 fmt.Println(t == r, &t == w, &t == rw) // false true true //类型断言 t = x.(T) r = t t = r.(T) //断言是具体类型 r = r.(Reader) //断言是接口类型 // w = r.(Writer) //断言失败,崩溃 // rw = n.(ReadWrite) //断言空接口值,肯定失败,崩溃 r, ok := r.(Reader) //断言返回二元组,如果成功返回值 和 true fmt.Println(r, ok) //123 true w, ok = r.(Writer) //断言返回二元组,如果失败返回 nil 和 false, 而不是崩溃 fmt.Println(w, ok) //<nil> fals //类型分支 switch rw := rw.(type) { //左边 rw 是新建的和右边 rw 同名的变量 case nil: //rw == nil 时 case Writer: // fallthrough //不能用 fallthrough case Reader: case ReadWrite: default: //以上都不满足时 default fmt.Sprintf("%T:%v", rw, rw) } }

    输出

    123 <nil> <nil> <nil> <nil> false true true 123 true <nil> false

    从源码分析接口类型

    //GOPATH\src\runtime\runtime2.go type iface struct { tab *itab data unsafe.Pointer } type eface struct { _type *_type data unsafe.Pointer } // layout of Itab known to compilers // allocated in non-garbage-collected memory // Needs to be in sync with // ../cmd/compile/internal/gc/reflect.go:/^func.dumptypestructs. type itab struct { inter *interfacetype _type *_type hash uint32 // copy of _type.hash. Used for type switches. _ [4]byte fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter. } //GOPATH\src\runtime\type.go // Needs to be in sync with ../cmd/link/internal/ld/decodesym.go:/^func.commonsize, // ../cmd/compile/internal/gc/reflect.go:/^func.dcommontype and // ../reflect/type.go:/^type.rtype. type _type struct { size uintptr ptrdata uintptr // size of memory prefix holding all pointers hash uint32 tflag tflag align uint8 fieldalign uint8 kind uint8 alg *typeAlg // gcdata stores the GC type data for the garbage collector. // If the KindGCProg bit is set in kind, gcdata is a GC program. // Otherwise it is a ptrmask bitmap. See mbitmap.go for details. gcdata *byte str nameOff ptrToThis typeOff }

    go 类型分类

    具体类型 int,string,struct{},…抽象类型 interface

    interface接口类型,无数据和方法,定义了一个方法集(一个多个方法声明,包含方法名和签名).不可以实例化,可以定义一个变量.

    接口类型

    itab 接口类型描述符(静态类型 inter)具体类型描述符(动态类型 _type)方法集(fun) 具体类型值(动态值 data)

    空接口类型

    具体类型描述符(动态类型 _type)具体类型值(动态值 data)
    最新回复(0)