用interface{}来指代一切类型
例子
编写一个Remove函数,Remove函数可以根据传入的元素的下标index,删除slice中的这个元素
函数原型func Remove(slice interface{},index int)
为了完成这个函数,所需要用到的知识
reflect,提供反射机制的package
什么是反射机制,我的理解就是反射机制代码在运行时,也能保留一些源代码信息。因为,实际上,程序运行的时候,在内存中是只有机器语言的。我们的源代码都统一编译成了汇编语言。reflect帮助我们记录下了这些源码信息。
如:
reflect.ValueOf()
会根据传入的参数生成一个reflect.Value
类型。这个类型中主要存储了两个东西是我们要用到的,一个是参数的类型,是int还是string之类的。还一个是参数内的数据。
interface{},空接口,可以把它当做C里的void类似的东西
golang里的任何类型都可以很轻易的转换成interface{}类型。你可以强转,也可以自动转换。
如
i := 10
var in interface{} = (interface{})(i)
//或者var in interface{} = i
但是将interface{}转换成其他类型就不能用强制转换了得这样
i = in.(int)
代码
package FuncSugar
import (
"reflect"
)
func toSlice(in interface{}) []interface{} {
v := reflect.ValueOf(in)
if v.Kind() != reflect.Slice {
//Kind()方法是reflect中Value类的一个方法,作用是返回一个Kind类型的枚举值,Slice是Kind枚举类型中的一个值,代表这是一个切片
panic("Function Remove in Package FuncSugar:Argument is wrong")
}
l := v.Len()
ans := make([]interface{}, l)//生成一个空接口数组
for i := 0; i < l; i++ {
ans[i] = v.Index(i).Interface()//reflect包下的Value类的Index方法像对待数组一样查看和获取Value类反射的数据,并转换成接口类型。这个Index可以处理Array,Slice,String三种类型。
}
return ans
}
func _remove(slice []interface{}, index int) []interface{} {
copy(slice[index:], slice[index+1:])
return slice[:len(slice)-1]
}
//这个是我们最终需要使用的函数,但是这个返回的是一个空接口数组,所以我们还得遍历这个数组来把它转换成原来的类型
func Remove(slice interface{}, index int) []interface{} {
return _remove(toSlice(slice), index)
}
调用
package main
import "FuncSugar"
func main() {
i := []int{1, 2, 3, 4}
temp := []int{}
for _, in := range FuncSugar.Remove(i, 2) { //比如我们要删掉下标2的元素
temp = append(temp, in.(int))
}
i = temp
fmt.Println(i)
}