本文内容是本人对Go语言的反射原理与使用的备忘录,记录了关键的相关知识点,以供翻查。 文中如有错误的地方请大家指出,以免误导!转摘本文也请注明出处:Go语言备忘录:反射的原理与使用详解,多谢! 参考书籍《Go语言圣经》、《Go语言实战》、《Go语言学习笔记》等
目录:
2.反射由reflect包提供支持,主要方法:
- v := reflect.ValueOf(&x)
- m := v.MethodByName("Show")
- in := []reflect.Value{
- reflect.ValueOf(23),
- reflect.ValueOf(323),
- }
- out := m.Call(in) //对于变参可用CallSlice方法
- var x float64 = 3.4
- p := reflect.ValueOf(&x) // 注意这里:把x地址传进去了!
- fmt.Println(p.Type()) //*float64
- fmt.Println(p.CanSet()) //false 这里的p只是指针,仍然是non-settable的
- v := p.Elem() //此时的v保存了x
- fmt.Println( v.CanSet()) //true
- v.SetFloat(7.1)
- fmt.Println(v.Interface()) //7.1
- fmt.Println(x) //7.1
虽然反射可以越过Go语言的导出规则的限制读取结构体中未导出的成员,但不能修改这些未导出的成员。因为一个struct中只有被导出的字段才是settable的。
- type T struct {
- A int B string
- }
- t: =T {
- 23,
- "skidoo"
- }
- s: =reflect.ValueOf( & t).Elem() typeOfT: =s.Type() //把s.Type()返回的Type对象复制给typeofT,typeofT也是一个反射。
- for i: =0;
- i < s.NumField();
- i++{
- f: =s.Field(i) //迭代s的各个域,注意每个域仍然是反射。
- fmt.Printf("%d: %s %s = %v\n", i, typeOfT.Field(i).Name, f.Type(), f.Interface()) //提取了每个域的名字
- }
- //0: A int = 23
- //1: B string = skidoo
- s.Field(0).SetInt(77) //s.Field(0).Set(reflect.ValueOf(77))
- s.Field(1).SetString("Sunset Strip") fmt.Println("t is now", t) //t is now {77 Sunset Strip}
- package main
- import("reflect""strings""fmt")
- //通用算法函数体模板
- func add(args[] reflect.Value)(results[] reflect.Value) {
- if len(args) == 0 {
- return nil
- }
- var r reflect.Value
- switch args[0].Kind() {
- case reflect.Int:
- n:
- =0
- for _,
- a: =range args {
- n += int(a.Int())
- }
- r = reflect.ValueOf(n)
- case reflect.String:
- ss:
- =make([] string, 0, len(args)) for _,
- s: =range args {
- ss = append(ss, s.String())
- }
- r = reflect.ValueOf(strings.Join(ss, ""))
- }
- results = append(results, r) return
- }
- func makeAdd(T interface {}) {
- fn: =reflect.ValueOf(T).Elem() v: =reflect.MakeFunc(fn.Type(), add) //把原始函数变量的类型和通用算法函数存到同一个Value中
- fn.Set(v) //把原始函数指针变量指向v,这样它就获得了函数体
- }
- func main() {
- //定义函数变量,未定义函数体
- var intAdd func(x, y int) int
- var strAdd func(a, b string) string
- makeAdd( & intAdd) makeAdd( & strAdd)
- fmt.Println(intAdd(12, 23)) //35
- fmt.Println(strAdd("hello, ", "world!")) //hello, world!
- }
posted on 2017-10-12 00:02 SuriFuture 阅读(...) 评论(...) 编辑 收藏
来源: http://www.cnblogs.com/susufufu/p/7653579.html