转载自 https://stackoverflow.com/questions/17262238/how-to-cast-reflect-value-to-its-type
43
9
How to cast reflect.Value to its type?
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
Thanks!
share improve this question follow
asked Jun 23 '13 at 15:23
29k2121 gold badges8080 silver badges127127 bronze badges
-
Go has no type casting. You can't cast anything. – Flimzy Dec 25 '18 at 13:11
4 Answers
54
concreteCat,_ := reflect.ValueOf(cat).Interface().(Cat)
see http://golang.org/doc/articles/laws_of_reflection.html fox example
type MyInt int
var x MyInt = 7
v := reflect.ValueOf(x)
y := v.Interface().(float64) // y will have type float64.
fmt.Println(y)
share improve this answer follow
29.3k3838 gold badges152152 silver badges273273 bronze badges
answered Dec 19 '13 at 8:05
1,54133 gold badges1313 silver badges1212 bronze badges
-
15
That's if you actually have knowledge of the type. In the case you would like to apply kind of a blind type assertion, I'm actually not sure it is possible. – Taye Aug 17 '14 at 11:00
-
One solution seems to be to leave the
reflect.Valueas-is and simply move all your calculations to using the reflect package without hope of ever converting to back to a regular struct. You can see this in gongular. Related: play.golang.org/p/Ok_q3lx490h – Xeoncross Mar 1 '18 at 4:28 -
2
It doesn't work.
panic: interface conversion: interface {} is main.MyInt, not float64– TomSawyer May 3 '18 at 19:47
33
Ok, I found it
reflect.Value has a function Interface() that converts it to interface{}
share improve this answer follow
72.8k2323 gold badges154154 silver badges296296 bronze badges
answered Jun 23 '13 at 15:32
29k2121 gold badges8080 silver badges127127 bronze badges
-
19
That converts it to interface{}. How do we convert it to the actual type? – Matt Dec 4 '13 at 16:40
-
1
It's not possible in Go, @Matt. You can't reinvent generics without unsafe or manual type conversions (in Go 1 at least). – Tejas Manohar Jan 31 '17 at 22:44
-
concreteCat, _ := cat.Interface().(Cat) is worked for me instead of reflect.ValueOf(cat).Interface().(Cat) – yountae.kang Aug 10 '18 at 3:01
-
@yountae.kang I'm not sure you found out why that happens, but either way the reason why cat.Interface().(Cat) works for you is because in the above use case cat is of type reflect.Value and there is no need to convert it to the reflect.Value type again. – hbn1991 Feb 20 '19 at 14:38
2
This func auto-converts types as needed. It loads a config file values into a simple struct based on struct name and fields:
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())
}
}
share improve this answer follow
answered Jan 2 at 18:13
25711 gold badge44 silver badges66 bronze badges
0
Seems the only way would be to do a switch statement similar to (code below) (also, something like the commented line would've-been nice though doesn't work (:()):
func valuesFromStruct (rawV interface{}) []interface{} {
v := reflect.ValueOf(rawV)
out := make([]interface{}, 0)
for i := 0; i < v.NumField(); i += 1 {
field := v.Field(i)
fieldType := field.Type()
// out = append(out, field.Interface().(reflect.PtrTo(fieldType)))
switch (fieldType.Name()) {
case "int64":
out = append(out, field.Interface().(int64))
break`enter code here`
case "float64":
out = append(out, field.Interface().(float64))
break
case "string":
out = append(out, field.Interface().(string))
break
// And all your other types (here) ...
default:
out = append(out, field.Interface())
break
}
}
return out
}
本文介绍如何在Go语言中使用反射将reflect.Value类型转换回其原始的具体类型,并提供了具体的代码示例。
590

被折叠的 条评论
为什么被折叠?



