varias studio programacion móviles graficos graficas desarrollo curso aplicaciones types type-conversion go

types - studio - programacion android pdf 2018



¿Cómo determinar el tipo "real" de un valor de interfaz{}? (6)

Aquí hay un ejemplo de decodificación de un mapa genérico utilizando tanto el interruptor como la reflexión, por lo que si no coincide con el tipo, utilice la reflexión para descubrirlo y luego agregue el tipo la próxima vez.

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) } }

No he encontrado un buen recurso para usar los tipos de interface{} . Por ejemplo

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) }

¿Conoces una buena introducción al uso de la interface{} de Go interface{} ?

preguntás especificas:

  • ¿Cómo obtengo el tipo "real" de w?
  • ¿Hay alguna manera de obtener la representación de cadena de un tipo?
  • ¿Hay alguna forma de usar la representación de cadena de un tipo para convertir un valor?

Los interruptores de tipo también se pueden usar con elementos de reflexión:

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") }


Puede usar la reflexión ( reflect.TypeOf() ) para obtener el tipo de algo, y el valor que le da ( Type ) tiene una representación de cadena (método String ) que puede imprimir.


También puede hacer cambios de tipo:

switch v := myInterface.(type) { case int: // v is an int here, so e.g. v + 1 is possible. fmt.Printf("Integer: %v", v) case float64: // v is a float64 here, so e.g. v + 1.0 is possible. fmt.Printf("Float64: %v", v) case string: // v is a string here, so e.g. v + " Yeah!" is possible. fmt.Printf("String: %v", v) default: // And here I''m feeling dumb. ;) fmt.Printf("I don''t know, ask .") }


Tu ejemplo funciona. Aquí hay una versión simplificada.

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

Utiliza aserciones de tipo .


Voy a ofrecer una forma de devolver un booleano basado en pasar un argumento de Reflejos de tipo a un receptor de tipo local (porque no pude encontrar nada como esto).

Primero, declaramos que nuestro tipo anónimo de tipo refleja. Valor:

type AnonymousType reflect.Value

Luego agregamos un constructor para nuestro tipo local AnonymousType que puede tomar cualquier tipo potencial (como interfaz):

func ToAnonymousType(obj interface{}) AnonymousType { return AnonymousType(reflect.ValueOf(obj)) }

Luego agregamos una función para nuestra estructura AnonymousType que afirma contra un reflect.Kind:

func (a AnonymousType) IsA(typeToAssert reflect.Kind) bool { return typeToAssert == reflect.Value(a).Kind() }

Esto nos permite llamar a lo siguiente:

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") }

Puede ver una versión más larga y funcional aquí: https://play.golang.org/p/EIAp0z62B7