reflect笔记

Cedrus · · 565 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

reflect使用和源码阅读的心得笔记。

TypeOf使用

package main

import (
    "fmt"
    "reflect"
)

type S struct {
    A float64 `usage:"a"`
    B float64 `usage:"b"`
    c float64 `usage:"c"`
}

func (s *S) Add() float64{
    return s.A + s.B
}

func (s *S) Del()float64{
    return s.A - s.B
}

func main() {
    s := S{1.43,2.15,3.24}
    t := reflect.TypeOf(s)//利用unsafe.Pointer的特性将S类型反射为emptyInterface类型,emptyInterface中的rtype定义与runtime里的_type对齐。
    fmt.Println(t)//main.S

    fmt.Println(t.Field(1))//{B  float64 usage:"b" 8 [1] false} 返回struct类型的第i个字段信息,从中可以获取到字段名,类型,tag,是否匿名等信息
    fmt.Println(t.FieldByName("c"))//{c main float64 usage:"c" 16 [2] false} true
    fmt.Println(t.Field(1).Name)// B
    fmt.Println(t.Field(1).Type)// float64
    fmt.Println(t.Field(1).Tag.Get("usage"))// b
    fmt.Println(t.Field(1).Anonymous)// false

    ps := reflect.TypeOf(&s)

    if ps.Kind() == reflect.Ptr{
        e := ps.Elem()//用于取类型的element type,比如指针指向的类型,slice、Map、Array、channel里面成员的类型,非以上类型panic
        fmt.Println(e.Field(0))//{A  float64 usage:"a" 0 [0] false}
    }
    //Slice的例子
    list := make([]S,0)
    list = append(list, s)
    ps2 := reflect.TypeOf(list)
    if ps2.Kind() == reflect.Slice{
        fmt.Println(ps2.Elem().Field(2))//{c main float64 usage:"c" 16 [2] false}
    }
}


VauleOf使用

package main

import (
    "fmt"
    "reflect"
)

type S struct {
    A float64 `usage:"a"`
    B float64 `usage:"b"`
    c float64 `usage:"c"`
}

func (s *S) Add() float64{
    return s.A + s.B
}

func (s *S) Del()float64{
    return s.A - s.B
}

func main() {
    s := S{1.43,2.15,3.24}
    v := reflect.ValueOf(s)//填充生成一个s具体类型对应的Value.此处实现也是使用unsafe.Pointer将S类型转换成emptyInterface类型的指针
    fmt.Println(v)//{1.43 2.15 3.24}
    fmt.Println(v.Field(1))//2.15 只有值的信息
    //fmt.Println(t.Method(0))//panic:因为方法的receiver类型是*S
    fmt.Println(v.Kind())//struct
    t := v.Type()//reflect.Value转换为reflect.Type
    fmt.Println(t.Field(2))//{c main float64 usage:"c" 16 [2] false}
    ps := &s
    pv := reflect.ValueOf(ps)
    fmt.Println(pv.Kind())//Ptr
    fmt.Println(pv.Elem())//{1.43 2.15 3.24} 返回指针ps指向或者interface ps包含的value,ps非这两种类型panic
    fmt.Println(pv.Elem().Field(1))//2.15
}

其他

待续


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:Cedrus

查看原文:reflect笔记

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

565 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传