我想传递一个结构体作为对函数的引用,并基于通过反射确定的函数类型,进行适当的转换并将值存储在结构体本身中。
但是,尽管代码运行了,并且在函数内部标识并转换了值,但是当控件返回到函数main()时,该结构没有我想要存储在其中的值。
代码如下:
package main
import (
"fmt"
"reflect"
"strconv"
)
type x struct {
f1 string
f2 int
f3 bool
}
func main() {
s := x{}
getData(&s.f1, "AAA")
getData(&s.f2, "1")
getData(&s.f3, "true")
fmt.Println(s)
}
func getData(data interface{}, value string) {
if value != "" {
switch reflect.TypeOf(data).String() {
case "*int":
data, _ = strconv.Atoi(value)
case "*bool":
data, _ = strconv.ParseBool(value)
case "*string":
data = value
}
}
}
在此示例中,我得到{ 0 false}
的同时期望{ AAA 1 true}
是否有任何 Golang GURU 可以告诉我这段代码在做什么?
在链接下进入游乐场 https://play.golang.org/p/l1_INJLOhAq
答案 0 :(得分:3)
根据值的类型,使用type switch执行代码。在这种情况下,无需使用反射。
func getData(data interface{}, value string) {
if value != "" {
switch data := data.(type) {
case *int:
*data, _ = strconv.Atoi(value)
case *bool:
*data, _ = strconv.ParseBool(value)
case *string:
*data = value
}
}
}
有关类型开关的更多信息:Go Tour,Go Specification,Effective Go。
答案 1 :(得分:1)
您需要使用reflect.Value.Elem()
而不是指针本身来获取实际值。
这里是要点:
func getData(data interface{}, value string) {
switch v := data.(type) {
case *int:
val := reflect.ValueOf(v).Elem()
intVal, _ := strconv.Atoi(value)
val.SetInt(int64(intVal))
}
}
我建议您阅读The Laws of Reflection