简析go中接口类型变量

接口类型变量拥有两种内部表示,分别用于不同接口类型的变量:

1.eface:用于表示没有方法的空接口类型变量,即interface{}类型的变量

2.iface:用于表示拥有方法的接口类型变量

空接口类型变量eface在运行时的表示为一个非导出结构体eface,该结构体包含字段_type和data。_type为该接口类型变量的动态类型的信息,data指向一个动态分配的内存空间,该内存空间存储的是赋值给接口类型变量的动态类型变量的值。

接口类型变量iface在运行时的表示为一个非导出结构体iface,该结构体包含字段tab和data。tab存储了接口类型变量的动态类型信息、接口的类型信息、方法列表以及动态类型所实现的方法的信息。data部分则同eface中的data。

两种接口类型变量的内部表示都可以简化看做是(类型信息,数据信息)。因此,要判断两种接口类型变量是否相等,需要判断两个接口类型变量的类型信息和数据信息是否相同。都相同时两种接口类型变量才是相同的。

判断两种接口类型变量是否相同,可以借助内置函数println,println可以打印出eface或者iface两个结构体(运行时中非导出结构体)中_type及data或tab及data两个字段的值,打印结果为(_type/tab,data)。println只接收字符串类型的参数,但是在参数类型为接口类型变量时,go编译器会将println转换为能够打印出两个字段的值的函数(指针值,此处不做深入探究)。下面看示例:

type i interface {
	M1()
	M2()
}

type T struct {
	m int
}

func (T) M1() {}
func (T) M2() {}

func main() {
	var ei interface{} // 空接口类型
	var ni i           // 非空接口类型
	println(ei)        // 此处空接口类型变量ei未赋初值,为nil接口类型变量,输出(0x0,0x0),表示类型信息和数 据信息均为空
	println(ni)        // 此处接口类型变量ni未赋初值, 为nil接口类型变量,输出(0x0,0x0)
	println(ei == ni)  // (0x0,0x0) == (0x0,0x0), 结果为true

	var e2 interface{} // 空接口类型
	var e3 interface{} // 空接口类型
	e2 = 1             // 空接口类型变量e2赋值
	e3 = 2             // 空接口类型变量e3赋值
	println(e2)        // 输出(0xc316c0,0xc51258)
	println(e3)        // 输出(0xc316c0,0xc51260)
	println(e2 == e3)  // 输出false。
	e3 = 1
	println(e2 == e3) // 输出true。即只有_type/tab和data两个字段值一样的时候两个接口类型变量才相等

	var ni1 i = nil     // 非空接口类型, 赋值nil
	var ni2 i           // 非空接口类型
	println(ni1)        // 输出(0x231668,0x0),即非空接口类型变量类型信息不空,数据为空
	println(ni1 == nil) // false。此处输出false结果是显而易见的

	ni1 = T{1}
	ni2 = T{2}
	println(ni1)        // 输出(0xaa1638,0xc000067f68)
	println(ni2)        // 输出(0xaa1638,0xc000067f60)
	println(ni1 == ni2) // 显然,此处nil1和nil2两个非空接口类型变量的类型信息相同,但是data信息不同,输出 false

	var e4 interface{} // 空接口类型
	var ni3 i          // 非空接口类型
	e4 = T{3}
	ni3 = T{3}
	println(e4)        // 输出(0x875ee0,0xc000067f58)
	println(ni3)       // 输出(0x891638,0xc000067f50)
	println(e4 == ni3) // 输出true。似乎出乎意料,居然是相等的。空接口类型变量和非空接口类型变量的比较,比 较的是空接口类型变量的_type和非空接口类型变量的tab._type,但println并未输出tab._type,而是输出的tab指针的值。
}

Go语言基础及实战 文章被收录于专栏

Go语言学习笔记、语法知识、技术要点和个人理解及实战

全部评论
楼主你现在就是从事go的工作吧
点赞 回复 分享
发布于 2023-04-04 22:33 广东
老哥你从事go几年了
点赞 回复 分享
发布于 2023-04-04 22:42 广东

相关推荐

10-30 22:18
已编辑
毛坦厂中学 C++
点赞 评论 收藏
分享
服从性笔试吗,发这么多笔,现在还在发。
蟑螂恶霸zZ:傻 x 公司,发两次笔试,两次部门匹配挂,
投递金山WPS等公司10个岗位 >
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务