如何确定一个接口{}值的“真实”types?
我还没有find使用interface{}
types的好资源。 例如
package main import "fmt" func weirdFunc(i int) interface{} { if i == 0 { return "zero" } return i } func main() { var i = 5 var w = weirdFunc(5) // this example works! if tmp, ok := w.(int); ok { i += tmp } fmt.Println("i =", i) }
你知道使用Go的interface{}
很好的介绍吗?
具体问题:
- 我如何得到“真正的”types的W?
- 有什么办法来获得一个types的string表示?
- 有什么方法可以使用types的string表示来转换值吗?
你的例子确实有效。 这是一个简化的版本。
package main import "fmt" func weird(i int) interface{} { if i < 0 { return "negative" } return i } func main() { var i = 42 if w, ok := weird(7).(int); ok { i += w } if w, ok := weird(-100).(int); ok { i += w } fmt.Println("i =", i) } Output: i = 49
它使用types断言 。
你也可以做types开关:
switch v := myInterface.(type) { case int: // v is an int here, so eg v + 1 is possible. fmt.Printf("Integer: %v", v) case float64: // v is a float64 here, so eg v + 1.0 is possible. fmt.Printf("Float64: %v", v) case string: // v is a string here, so eg v + " Yeah!" is possible. fmt.Printf("String: %v", v) default: // And here I'm feeling dumb. ;) fmt.Printf("I don't know, ask stackoverflow.") }
您可以使用reflection( reflect.TypeOf()
)来获取某种types的东西,并且它给出的值( Type
)具有可以打印的string表示forms( String
方法)。
下面是使用开关和reflection对通用映射进行解码的示例,所以如果您不匹配types,请使用reflection来计算出来,然后在下次添加types。
var data map[string]interface {} ... for k, v := range data { fmt.Printf("pair:%s\t%s\n", k, v) switch t := v.(type) { case int: fmt.Printf("Integer: %v\n", t) case float64: fmt.Printf("Float64: %v\n", t) case string: fmt.Printf("String: %v\n", t) case bool: fmt.Printf("Bool: %v\n", t) case []interface {}: for i,n := range t { fmt.Printf("Item: %v= %v\n", i, n) } default: var r = reflect.TypeOf(t) fmt.Printf("Other:%v\n", r) } }
types开关也可以用于reflection的东西:
var str = "hello!" var obj = reflect.ValueOf(&str) switch obj.Elem().Interface().(type) { case string: log.Println("obj contains a pointer to a string") default: log.Println("obj contains something else") }
我将提供一种方法来返回一个布尔值,基于将reflectionKinds的parameter passing给本地types接收器(因为我找不到这样的东西)。
首先,我们声明我们的匿名types反映。值:
type AnonymousType reflect.Value
然后,我们为本地typesAnonymousType添加一个构build器,它可以采用任何可能的types(作为接口):
func ToAnonymousType(obj interface{}) AnonymousType { return AnonymousType(reflect.ValueOf(obj)) }
然后我们为我们的AnonymousType结构添加一个函数,该函数针对reflect.Kind声明:
func (a AnonymousType) IsA(typeToAssert reflect.Kind) bool { return typeToAssert == reflect.Value(a).Kind() }
这使我们可以调用以下内容:
var f float64 = 3.4 anon := ToAnonymousType(f) if anon.IsA(reflect.String) { fmt.Println("Its A String!") } else if anon.IsA(reflect.Float32) { fmt.Println("Its A Float32!") } else if anon.IsA(reflect.Float64) { fmt.Println("Its A Float64!") } else { fmt.Println("Failed") }
在这里可以看到一个更长的工作版本: https : //play.golang.org/p/EIAp0z62B7