type golang check cast go type-mismatch

check - golang interface type assertion



no puede convertir datos(escriba interface{}) para escribir string: need type assertion (3)

Escriba Afirmación

Esto se conoce como type assertion en golang, y es una práctica común.

Aquí está la explicación de un recorrido de ida :

Una aserción de tipo proporciona acceso al valor concreto subyacente de un valor de interfaz.

t := i.(T)

Esta afirmación afirma que el valor de interfaz i posee el tipo concreto T y asigna el valor T subyacente a la variable t.

Si no tengo una T, la declaración provocará un ataque de pánico.

Para probar si un valor de interfaz posee un tipo específico, una aserción de tipo puede devolver dos valores: el valor subyacente y un valor booleano que informa si la aserción tuvo éxito.

t, ok := i.(T)

Si tengo una T, entonces t será el valor subyacente y la respuesta correcta será verdadera.

Si no, ok será falso y t será el valor cero de tipo T, y no se producirá pánico.

NOTA: valor i debe ser tipo de interfaz .

Trampas

Incluso si soy un tipo de interfaz, []i no es tipo de interfaz. Como resultado, para convertir []i a su tipo de valor, tenemos que hacerlo individualmente:

// var items []i for _, item := range items { value, ok := item.(T) dosomethingWith(value) }

Actuación

En cuanto al rendimiento, puede ser más lento que el acceso directo al valor real como se muestra en esta respuesta de stackoverflow .

Soy bastante nuevo para ir y estaba jugando con este paquete de notify .

Al principio tenía un código que se veía así:

func doit(w http.ResponseWriter, r *http.Request) { notify.Post("my_event", "Hello World!") fmt.Fprint(w, "+OK") }

¡Quería añadir newline a Hello World! pero no en la función doit arriba, porque eso sería bastante trivial, pero en el handler luego como este a continuación:

func handler(w http.ResponseWriter, r *http.Request) { myEventChan := make(chan interface{}) notify.Start("my_event", myEventChan) data := <-myEventChan fmt.Fprint(w, data + "/n") }

Después de go run :

$ go run lp.go # command-line-arguments ./lp.go:15: invalid operation: data + "/n" (mismatched types interface {} and string)

Después de un poco de Google, encontré esta pregunta en SO .

Luego actualicé mi código a:

func handler(w http.ResponseWriter, r *http.Request) { myEventChan := make(chan interface{}) notify.Start("my_event", myEventChan) data := <-myEventChan s:= data.(string) + "/n" fmt.Fprint(w, s) }

¿Es esto lo que se suponía que debía hacer? Mis errores de compilación se han ido, así que supongo que eso es bastante bueno. ¿Es esto eficiente? ¿Deberías hacerlo de manera diferente?


De acuerdo con la especificación Go :

Para una expresión x del tipo de interfaz y un tipo T, la expresión primaria x. (T) afirma que x no es nulo y que el valor almacenado en x es de tipo T.

Una "afirmación de tipo" le permite declarar que un valor de interfaz contiene un cierto tipo concreto o que su tipo concreto satisface otra interfaz.

En su ejemplo, usted estaba afirmando datos (type interface {}) tiene la cadena de tipo concreto. Si está equivocado, el programa entrará en pánico en el tiempo de ejecución. No necesita preocuparse por la eficiencia, la comprobación solo requiere comparar dos valores de puntero.

Si no estaba seguro de si era una cadena o no, podría probar usando la sintaxis de dos retornos.

str, ok := data.(string)

Si los datos no son una cadena, ok será falso. Entonces es común incluir dicha declaración en una declaración if como esta:

if str, ok := data.(string); ok { /* act on str */ } else { /* not string */ }


//an easy way: str := fmt.Sprint(data)