Golang Reflect

1 前言

    reflect.Value //值
    reflect.Type  //类型
    p := struct{
        Name string
        Value string
    }{
        Name:"n",
        Value:"v",
    }
    t := reflect.TypeOf(p)   
    v := reflect.ValueOf(p)
    Bool
    Int
    Int8
    Int16
    Int32
    Int64
    Uint
    Uint8
    Uint16
    Uint32
    Uint64
    Uintptr
    Float32
    Float64
    Complex64
    Complex128
    Array       //数组
    Chan        //channel
    Func        //函数
    Interface   //
    Map         //map
    Ptr         //指针
    Slice       //切片
    String      //字符串
    Struct      //结构体
    UnsafePointer

2 未知参数的解析

    for i := 0; i < t.NumField(); i++ {
        f := t.Field(i)  //获取结构体属性类型,可以用来获取tag等
        vf := v.Field(i) //获取结构体属性具体值
    }
    iter := v.MapRange()//获取map迭代器
    for iter.Next() {
        k := iter.Key()     //K/V都是value对象,可以进一步解析
        iv := iter.Value()
        //TODO k/v
    }
    if v.kind() == reflect.Slice || v.kind() == reflect.Array  {
        for idx := 0 ;idx < iv.Len() ; idx ++ {
            currValue := iv.Index(idx)//获取切片或数组中的某一元素
            //TODO currvalue
        }
    }

3 未知参数的创建

    //以下两种获取方式都可以
    //这里忽略int等基础类型,主要针对于结构体,结构体指针等
    t := reflect.TypeOf(p)
    t:=reflect.ValueOf(p).Type()
     sptr := reflect.New(t)//此时得到结构体指针
     structValue := sptr.Elem() //此时获得结构体变量
    elemType := reflect.ValueOf(p).Type() //获取切片单个元素的类型
    sliceType := reflect.SliceOf(elemType) //获取结构体切片类型
    sliceValue := reflect.MakeSlice(sliceType, 0, 0) //创建切片
    slicePtr := reflect.New(sliceValue.Type()) //创建切片指针
    //获取k/v类型
    kType := reflect.TypeOf(key)
    vType := reflect.TypeOf(value)
    //获取要创建的map Type
    mType := reflect.MapOf(kType,vType)
    //创建这个map
    mapValue := reflect.MakeMap(mType)//make
    results := reflect.New(mapValue.Type())//指针

4 未知参数的赋值

    //假设我们获取了一个struct的类型t
    for i := 0; i < t.NumField(); i++ {
        vf := v.Field(i) //获取结构体属性具体值
        vf.Set(reflect.ValueOf(1)) //给这个属性赋值
        //更多个性化赋值
        // vf.SetString("1") 
        // vf.SetInt(1)
        // vf.SetBool(true)
        // ...
    }