Golang数据作为接口{}死机



Gophers,

我正在尝试实现Go的反射包,但我确实坚持了一件事。

context-我正在尝试调用一个返回时间的API。接口{}中的时间和一些数据。在大多数情况下,该数据可以是int/int64或float32/float64。我获取接口{}中的数据,并进一步创建一个结构,在其中我将接口{}中的数据保留为反射,这承诺了我可以用接口做一些奇特的事情

type dataStore struct {
CreateTime time.Time
Data interface{}
}

然后我创建一个map[string][]dataStore来存储我从API获取的数据。

我正在尝试做以下操作,以获得我知道即将到来的Float64值,我想对它们进行一些计算:

x := map[string][]dataStore {}
ReadDatafromAPI(x) // I call the API to read the data into variable x
//Assume map["CA"][]dataStore{{2020-03-31 21:55:52.123456, 123.4567890123e10},}
fmt.Println(x["CA"][0].Data) // This prints the data 123.4567890123e10, no problem
fmt.Println(reflect.ValueOf(x["CA"][0].Data))// this prints reflect.Value
va := reflect.ValueOf(x["CA"][0].Data) 
fmt.Println(va.(float64)) // panic: interface conversion: interface {} is reflect.Value, not float64
fmt.Println(va.Interface()) // prints 123.4567890123e10
fmt.Println(va.Kind()) // prints struct
fmt.Println(va.NumField()) // prints 2 and I can fetch the fields using Field(0) and Field(1) -- the data doesn't make sense to me. not sure if those are pointers or what

我只有一个目标——将float64作为float64,将int作为int。这意味着use反映了它应该使用的方式。

任何见解都将不胜感激。

提前谢谢。


各位-感谢所有的答案和建议。我很感激!看来我还是会反思的。值作为类型,而不是预期的float64/32。见下文:

switch flt := x["CA"][0].Data.(type) {
case float64:
fmt.Println("Data is float64 -> ", flt)
fmt.Printf("Type for flt is %T -> ", flt)
case float32:
fmt.Println("Data is float32 -> ", flt)
fmt.Printf("Type for flt is %T -> ", flt)
default:
fmt.Println("Its default!")
fmt.Printf("Type for flt is %T -> ", flt) // I always get here with reflect.Value as the Type. Never a float64 which is the value store without any question
}

if nflt, ok := x["CA"][0].Data.(float64); ok {
fmt.Println("nflt is float64")
} else {
fmt.Println("nflt is not float64) // I always get to Else
}

您不需要反射就可以将接口转换为已知类型之一。您需要类型断言或类型切换:

if flt, ok:=data.(float64); ok {
// flt is float64
}
if i, ok:=data.(int); ok {
// i is int
}

或者:

switch k:=data.(type) {
case float64:
// Here, k is float64
case int:
// Here, k is int
}

使用两个值类型的断言来获得值而不会恐慌:

d, ok := (x["CA"][0].Data.(float64)
if ok {
// it's a float64, do something with d.
}

或者使用类型开关:

switch d := x["CA"][0].Data.(type) {
case int:
// d is an int
case float64:
// d is a float64
... and other types as needed
default:
// handle unexpected type
}

最新更新