Golang reflect和interface{}

本文探讨了Golang中的empty interface、类型断言和类型切换。通过一个函数示例,解释了当对象作为非指针传递时,如何在原对象上进行排序,这涉及到interface的内部结构和数据传递方式。内容详细分析了interface的数据结构,指出在转换为empty interface后,保存的是原始数据的指针,而非拷贝,因此函数可以直接修改原始数据。同时,文章还涉及了`fmt.Println`在处理interface{}时的特殊行为。
摘要由CSDN通过智能技术生成

preliminary
empty interfacetype assertiontype switch

探究这个问题的缘由:使用sort.Slice(slice interface{}, less func(i int, j int) bool)函数,比如下面的代码示例,我传入sort.Slice的第一个参数是对象而不是指针,如果算作值传递的话应该会引起对象拷贝,sort.Slice函数只是在对拷贝做排序,不影响原对象,而实际结果是如图所示即在原对象上进行了排序。

slice := []int{
   4, 3, 1, 2, 5}
sort.Slice(slice, func(i, j int) bool {
   
	if slice[i] < slice[j] {
   
		return true
	}
	return false
})
fmt.Println(slice)  // [1 2 3 4 5]

这个问题很明显地就出在了interface{}这个可以代表任何类型的符号上了(或者说任何类型都实现了interface{})。在Go Data Structures: Interfaces中解释了interface的数据结构,即一个指向interface table的指针和一个指向被转换为interface的数据的指针,由于在本例中使用的是interface{},所以第一个指针可以被简化为指向类型的指针(对应为src/reflect/type.go:296的rtype),而文中说第二个指针在数据可以fit进一个word的时会直接拷贝,这个我实测倒没有发生。总而言之,在变量a被转换为empty interface变量b之后,b中保存着指向a的数据的指针,而非拷贝。 于是sort.Slice函数可以利用指针直接改变原有数组的排列。

再来看一下sort.Slice的实现

func Slice(slice interface{
   }, less func(i, j int) bool) {
   
	rv := reflect.ValueOf(slice)
	swap := reflect.Swapper(slice)
	length := rv.Len()
	quickSort_func(lessSwap{
   less, swap}, 0, length, maxDepth(length))
}

reflect.Swapper函数中其实也使用了reflect.ValueOf函数࿰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值