如何将reflect.Value转换为其类型?

Ale*_*lex 27 reflection go

如何将reflect.Value转换为其类型?

type Cat struct { 
    Age int
}

cat := reflect.ValueOf(obj)
fmt.Println(cat.Type()) // Cat

fmt.Println(Cat(cat).Age) // doesn't compile
fmt.Println((cat.(Cat)).Age) // same
Run Code Online (Sandbox Code Playgroud)

谢谢!

sha*_*ind 45

concreteCat,_ := reflect.ValueOf(cat).Interface().(Cat)
Run Code Online (Sandbox Code Playgroud)

请参阅http://golang.org/doc/articles/laws_of_reflection.html fox示例

type MyInt int
var x MyInt = 7
v := reflect.ValueOf(x)
y := v.Interface().(float64) // y will have type float64.
fmt.Println(y)
Run Code Online (Sandbox Code Playgroud)

  • 如果你真的知道这种类型的话就是这样.在你想要应用一种盲式断言的情况下,我实际上不确定它是否可行. (13认同)
  • 没用 `panic:interface conversion:interface {}是main.MyInt,而不是float64。 (2认同)

Ale*_*lex 26

好的,我找到了

reflect.Value有一个Interface()将其转换为的函数interface{}

  • 这将它转换为接口{}.我们如何将其转换为实际类型? (16认同)
  • 这在 Go 中是不可能的,@Matt。如果没有不安全或手动类型转换,你就无法重新发明泛型(至少在 Go 1 中)。 (2认同)

rri*_*bas 5

此 func 根据需要自动转换类型。它根据结构名称和字段将配置文件值加载到一个简单的结构中:

import (
    "fmt"
    toml "github.com/pelletier/go-toml"
    "log"
    "os"
    "reflect"
)
func LoadConfig(configFileName string, configStruct interface{}) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("LoadConfig.Recovered: ", r)
        }
    }()
    conf, err := toml.LoadFile(configFileName)
    if err == nil {
        v := reflect.ValueOf(configStruct)
        typeOfS := v.Elem().Type()
        sectionName := getTypeName(configStruct)
        for i := 0; i < v.Elem().NumField(); i++ {
            if v.Elem().Field(i).CanInterface() {
                kName := conf.Get(sectionName + "." + typeOfS.Field(i).Name)
                kValue := reflect.ValueOf(kName)
                if (kValue.IsValid()) {
                    v.Elem().Field(i).Set(kValue.Convert(typeOfS.Field(i).Type))
                }
            }
        }
    } else {
        fmt.Println("LoadConfig.Error: " + err.Error())
    }
}
Run Code Online (Sandbox Code Playgroud)