本文主要是介绍go interface 类型用法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一个例子短平快的了解 interface 的语法
-
接口定义
-
接口实现
-
接口零值 nil
-
表达式实现接口的方法,可以赋值给接口变量
- 实例赋值给接口
- 指针赋值给接口
- 接口赋值给接口
-
T 型值方法集 (t T)
-
*T 型值方法集 (t T) 和 (t *T)
-
判等,可赋值,可判等
-
类型断言 t = x.(T)
- 断言是具体类型
- 断言是接口类型
- 断言失败,崩溃
- 断言空接口值,肯定失败,崩溃
- 断言返回二元组,如果成功返回值 和 true
- 断言返回二元组,如果失败返回 nil 和 false, 而不是崩溃
-
类型分支
例子
package mainimport "fmt"//接口定义
type Reader interface {Read() T
}//
type Writer interface {Write(arg T)
}//
type ReadWrite interface {Read() TWrite(arg T)
}// 接口实现
type T int64func (t T) Read() T {return t
}
func (t *T) Write(arg T) {*t = arg
}func main() {var t T = 123var r Readervar w Writervar rw ReadWritevar n ReadWrite//接口零值nilfmt.Println(t, r, w, rw, n) //123 <nil> <nil> <nil> <nil>//表达式实现接口的方法,可以赋值给接口变量r = t //实例赋值给接口rw = &t //指针赋值给接口w = rw //接口赋值给接口// T 型值方法集 (t T) ,这里 Readr = t//w = t //(t *T) 型方法不是 T 型值的方法集//T(10).Write(t) //(t *T) 型方法不是 T 型值的方法集 <== T(10) 无法取地址,无法调用 Write 方法// *T 型值方法集 (t T) 和 (t *T), 这里 Read Writer = &tw = &t//判等,可赋值,可判等fmt.Println(t == r, &t == w, &t == rw) // false true true//类型断言 t = x.(T)r = tt = r.(T) //断言是具体类型r = r.(Reader) //断言是接口类型// w = r.(Writer) //断言失败,崩溃// rw = n.(ReadWrite) //断言空接口值,肯定失败,崩溃r, ok := r.(Reader) //断言返回二元组,如果成功返回值 和 truefmt.Println(r, ok) //123 truew, ok = r.(Writer) //断言返回二元组,如果失败返回 nil 和 false, 而不是崩溃fmt.Println(w, ok) //<nil> fals//类型分支switch rw := rw.(type) { //左边 rw 是新建的和右边 rw 同名的变量case nil: //rw == nil 时case Writer:// fallthrough //不能用 fallthroughcase Reader:case ReadWrite:default: //以上都不满足时 defaultfmt.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 *itabdata unsafe.Pointer
}type eface struct {_type *_typedata 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 *_typehash uint32 // copy of _type.hash. Used for type switches._ [4]bytefun [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 uintptrptrdata uintptr // size of memory prefix holding all pointershash uint32tflag tflagalign uint8fieldalign uint8kind uint8alg *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 *bytestr nameOffptrToThis typeOff
}
go 类型分类
- 具体类型 int,string,struct{},…
- 抽象类型 interface
interface接口类型,无数据和方法,定义了一个方法集(一个多个方法声明,包含方法名和签名).不可以实例化,可以定义一个变量.
接口类型
- itab
- 接口类型描述符(静态类型 inter)
- 具体类型描述符(动态类型 _type)
- 方法集(fun)
- 具体类型值(动态值 data)
空接口类型
- 具体类型描述符(动态类型 _type)
- 具体类型值(动态值 data)
这篇关于go interface 类型用法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!