reflect筆記
摘要:
reflect使用和原始碼閱讀的心得筆記。
TypeOf使用
package main
import (
"fmt"
"reflect"
)
type S struct {
A float64 `usage:"a...
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))//{Bfloat64 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))//{Afloat64 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 }
其他
待續