golang的interface的实现

66 阅读2分钟

golang的interface的实现

参考链接

golang是如何判断一个对象(interface和其他)是否为nil的呢?

interface

结构

type iface struct {
	tab  *itab   // 存储接口本身的信息
	data unsafe.Pointer // 指向具体类型变量的值。
}

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.
}

type eface struct {
	_type *_type // 具体的类型信息
	data  unsafe.Pointer // 指向具体类型变量的值。
}
  • iface表示拥有方法的接口变量
type IPerson interface {
  GetName() string
}
type Man struct {}
func (this *Man)GetName()string{
  return "张三"
}

var person IPerson = &Man{} // 则 person就是 iface
  • eface表示没有方法的空接口变量
var itmp interface
itmp = 123 // 任何对象  itmp就是 eface

实例分析

println 打印interface的使用实现函数,通过dlv或者 go build -gcflags="-N -l -S" main.go 查看汇编输出即可

// eface的打印
func printeface(e eface) {
	print("(", e._type, ",", e.data, ")")
}

// iface的打印
func printiface(i iface) {
	print("(", i.tab, ",", i.data, ")")
}
  • eface
package main

type User struct{}

func main() {
	var iuterface interface{}
	println("[打印a]", iuterface)
	println("[打印b]", iuterface == nil)

	var userRes *User
	iuterface = userRes
	println("[打印c]",iuterface)
	println("[打印d]", iuterface == nil)
}

/* --- 打印结果
[打印a] (0x0,0x0)
[打印b] true
[打印c] (0x10022a580,0x0)
[打印d] false
*/

分析结果

0、[打印a] (0x0,0x0),eface的type 和 data都是空

0、[打印b] true ,当判断 ==nil时候,因为,iuterface 的 type和data都是空,所以true,

0、定义*User类型对象 userRes ,初始是nil,赋值给 iuterface

0、[打印c] (0x10022a580,0x0) ,则表示,iuterface.type 有值,但是data空

0、[打印d] false ,判断 是否为nil是,因为iuterface 的 type 和data有一个不为空,则表示不为nil,

  • iface
package main

type IPerson interface {
	GetName() string
}
type Man struct{}

func (this *Man) GetName() string {
	return "张三"
}

func main() {
	var person IPerson
	println("[打印a]", person)
	println("[打印b]", person == nil)
  
  var man *Man
	person = man
	println("[打印c]", person)
	println("[打印d]", person == nil)
}

/*
打印结果
[打印a] (0x0,0x0)
[打印b] true
[打印c] (0x104284108,0x0)
[打印d] false
*/

分析结果

0、[打印a] (0x0,0x0),iface的type 和 data都是空

0、[打印b] true ,当判断 ==nil时候,因为,IPerson 的 tab和data都是空,所以true,

0、定义*Man类型对象 man 是IPerson接口实现者 ,初始是nil,赋值给 IPerson

0、[打印c] (0x104284108,0x0) ,则表示,person.tab 有值,但是data空

0、[打印d] false ,判断 是否为nil是,因为person 的 tab 和data有一个不为空,则表示不为nil,

总结

  • 判断一个对象是否是nil,如果这个对象是interface,则iface或者eface中成员变量都为空则表示 nil,否则不为nil
  • 判断一个对象是否是nil,如果这个对象不是interface,则对象没有被初始化则为nil