一、使用反射与接口实现泛型
package main
import (
"fmt"
"reflect"
)
//定义一个结构体
type Container struct {
s reflect.Value
}
//初始化容器
func NewContainer(t reflect.Type,size int) *Container {
if size <= 0 {
size = 64
}
//基于切片类型实现容器,使用反射初始化底层切片
return &Container{
//创建切片
s : reflect.MakeSlice(reflect.SliceOf(t),0,size),
}
}
//添加元素到容器
func (c *Container) Put(val interface{}) error {
//对元素类型进行检测
if reflect.ValueOf(val).Type() != c.s.Type().Elem() {
return fmt.Errorf("put error: cannot put a %T into a slice of %s",val,c.s.Type().Elem())
}
//类型检测成功就添加到容器中
value := reflect.Append(c.s, reflect.ValueOf(val))
c.s = value
return nil
}
//从容器中读取元素
func (c *Container) Get(val interface{}) error {
//对元素类型进行检测
if reflect.ValueOf(val).Kind() != reflect.Ptr || reflect.ValueOf(val).Elem().Type() != c.s.Type().Elem() {
return fmt.Errorf("get error: needs *%s but got %T",c.s.Type().Elem(),val)
}
//将容器第一个索引位置赋值给val指针
reflect.ValueOf(val).Elem().Set(c.s.Index(*(val.(*int))))
//删除容器第一索引位置
slice := c.s.Slice(1, c.s.Len())
c.s = slice
return nil
}
func main() {
ints := []int{1, 2, 3, 4, 5}
//调用函数初始化容器
container := NewContainer(reflect.TypeOf(ints[0]), 16)
//添加元素到容器
for _, n := range ints {
if err := container.Put(n); err != nil {
panic(err)
}
}
//从容器中读取元素
num := 3
if err := container.Get(&num); err != nil {
panic(err)
}
fmt.Println("取出的结果为:",num)
}