go interface 类型用法

一个例子短平快的了解 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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值