如何确定一个接口{}值的“真实”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