第11章 2.反射

2020-01-18  本文已影响0人  yezide

1、 方法和类型的反射

package main

import "fmt"
import "reflect"


func main() {
    var f1 float64 = 1.1
    var type1 reflect.Type
    type1 = reflect.TypeOf(f1)
    fmt.Println("type: ", type1)

    value1 := reflect.ValueOf(f1);
    fmt.Println("value1: ", value1)
    fmt.Println("value1's type: ", value1.Type())
    fmt.Println("value1's kind: ", value1.Kind())
    fmt.Println("value1's Interface: ", value1.Interface())

    // 下面我们将尝试用反射修改f1的值. 
    // 将会导致错误: panic: reflect: reflect.Value.SetFloat using unaddressable value
    // 因为v不可以设置
    // value1.SetFloat(2.2)

    // 要想设置, 要传入f1的指针地址, 再用Elem()
    // 好麻烦
    value2 := reflect.ValueOf(&f1)
    value2 = value2.Elem()
    value2.SetFloat(2.2)
    fmt.Println("value2: ", value2)
}

2、结构的反射

package main

import "fmt"
import "reflect"

type NotknownType struct {
    s1, s2, s3, S4 string
}

func (n NotknownType) String() string {
    return n.s1 + " - " + n.s2 + " - " + n.s3 + "-" + n.S4
}

// variable to investigate:
var secret1 interface{} = NotknownType{"str1", "str2", "str3", "Str4"}
type secret2 struct {
    Str string
}


func main() {
    type1 := reflect.TypeOf(secret1)
    value1 := reflect.ValueOf(secret1)

    fmt.Println("type: ", type1)
    fmt.Println("value: ", value1)
    fmt.Println("Kind: ", value1.Kind())

    // 看结构体中各个类型的字段
    for i := 0; i < value1.NumField(); i++ {
        field1 := value1.Field(i)
        fmt.Printf("before Field %d: value=%v kink=%v\n", i,field1, field1.Kind())
        // 此时如果想设置值会报错. 因为s1是非导出类型(可以理解为private的)
        // field1.SetString("1")
    }

    // 设置值, 有点绕
    s2 := secret2{"1"}
    value2 := reflect.ValueOf(&s2).Elem()
    value2.Field(0).SetString("2")
    fmt.Printf("value2=%s\n", value2)
}
上一篇 下一篇

猜你喜欢

热点阅读