设为首页 加入收藏

TOP

golang的reflection(转)(二)
2018-11-15 00:08:27 】 浏览:384
Tags:golang reflection
fset uintptr Index []int Anonymous bool } *
*/ f := t.Field(i) //使用结构体方法v.Field(i)根据下标i获取字段Value(Id,Name,Age) //在根据Value的Interface()方法获取当前的value的值(interface类型) val := v.Field(i).Interface() fmt.Printf("%6s:%v = %v\n", f.Name, f.Type, val) } //使用t.NumMethod()获取所有结构体类型的方法个数(只有Hello()一个方法) //接口Type的方法NumMethod() int for i := 0; i < t.NumMethod(); i++ { //使用t.Method(i)指定方法下标获取方法对象。返回一个Method结构体 //Method(int) Method m := t.Method(i) //打印Method结构体的相关属性 /* type Method struct { Name string PkgPath string Type Type Func Value Index int } */ fmt.Printf("%6s:%v\n", m.Name, m.Type) } }

 

输出

type: User
Fields:
    Id:int = 1
  Name:string = bgops
   Age:int = 25
 Hello:func(main.User)
Hello xuxuebiao

 

注意:我们上面的示例是使用值类型进行进行反射构造的。如果是指针类型的话,我们需要使用reflect.Struct字段进行判断接口类型的Kind()方法

if k := t.Kind();k != reflect.Struct {
    fmt.Println("非值类型的反射")
    return
}

 

匿名字段的反射以及嵌入字段

注意:反射会将匿名字段当做独立的字段去处理,需要通过类型索引方式使用FieldByIndex方法去逐个判断

//根据指定索引返回对应的嵌套字段
FieldByIndex(index []int) StructField

type StructField struct {
    Name    string
    PkgPath string
    Type    Type
    Tag     StructTag
    Offset  uintptr
    Index   []int
    Anonymous   bool //是否为匿名字段
}
package main

import (
    "fmt"
    "reflect"
)

type User struct {
    Id   int
    Name string
    Age  int
}

type Manager struct {
    User
    title string
}

func main() {
    //注意匿名字段的初始化操作
    m := Manager{User: User{1, "biaoge", 24}, title: "hello biao"}
    t := reflect.TypeOf(m)

    fmt.Printf("%#v\n", t.FieldByIndex([]int{0}))
    fmt.Printf("%#v\n", t.FieldByIndex([]int{1}))
    fmt.Printf("%#v\n", t.FieldByIndex([]int{0, 0}))
    fmt.Printf("%#v\n", t.FieldByIndex([]int{0, 1}))

}

输出:

reflect.StructField{Name:"User", PkgPath:"", Type:(*reflect.rtype)(0x4ac660), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:true}
reflect.StructField{Name:"title", PkgPath:"main", Type:(*reflect.rtype)(0x49d820), Tag:"", Offset:0x20, Index:[]int{1}, Anonymous:false}
reflect.StructField{Name:"Id", PkgPath:"", Type:(*reflect.rtype)(0x49d1a0), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:false}
reflect.StructField{Name:"Name", PkgPath:"", Type:(*reflect.rtype)(0x49d820), Tag:"", Offset:0x8, Index:[]int{1}, Anonymous:false}

 

通过反射修改目标对象

通过反射的方式去修改对象的某个值。需要注意的亮点是,首先,需要找到对象相关的名称,其次需要找到合适的方法去修改相应的值。

package main

import (
    "fmt"
    "reflect"
)

func main() {
    x := 123
    v := reflect.ValueOf(&x)
    v.Elem().SetInt(5256)
    fmt.Println(x)
}

 

输出:

5256
修改I的时候需要找到对象字段的名称;并且判断类型,使用相对正确的类型修改值
v.FieldByName("Name");f.Kind() == reflect.String {
    f.SetString("test string")
}

判断是否找到正确的字段名称:

f := v.FieldByName("Name1")
//判断反射对象Value中是否找到Name1字段
if !f.IsValid() {
    fmt.Println("bad field")
    return
}
package main

import (
    "fmt"
    "reflect"
)

type User struct {
    Id   int
    Name string
    Age  int
}

//使用反射方式对结构体对象的修改有两个条件
//1.通过指针
//2.必须是可set的方法
func main() {
    num := 123
    numv := reflect.ValueOf(&num)
    //通过Value的Elem()和SetX()方法可直接对相关的对象进行修改
    numv.Elem().SetInt(666)
    fm
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇golang cgo 使用总结 下一篇【golang-GUI开发】QSS的使用(一)..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目