Soy nuevo en interfaces e intento hacer una solicitud SOAP por github
No entiendo el significado de
Msg interface{}
en este código:
type Envelope struct {
Body `xml:"soap:"`
}
type Body struct {
Msg interface{}
}
He observado la misma sintaxis en
fmt.Println
pero no entiendo lo que se está logrando con
interface{}
interface{}
es más o menos el equivalente devoid *
en C. Puede apuntar a cualquier cosa y necesita una aserción de conversión / tipo para usarlo.Respuestas:
Puede consultar el artículo " Cómo usar interfaces en Go " (basado en la " Descripción de interfaces de Russ Cox "):
(Eso es lo que
Msg
representa en su pregunta: cualquier valor)Anexo: Esto es donde el artículo de Russ es bastante completo con respecto a una estructura de interfaz:
fuente
interface{}
significa que puede poner valor de cualquier tipo, incluido su propio tipo personalizado. Todos los tipos en Go satisfacen una interfaz vacía (interface{}
es una interfaz vacía).En su ejemplo, el campo Msg puede tener un valor de cualquier tipo.
Ejemplo:
Ir al patio de recreo
fuente
Se llama interfaz vacía y está implementado por todos los tipos, lo que significa que puede poner cualquier cosa en el
Msg
campo.Ejemplo:
Esta es la extensión lógica del hecho de que un tipo implementa una interfaz tan pronto como tiene todos los métodos de la interfaz.
fuente
Ya hay buenas respuestas aquí. Permítanme agregar el mío también para otros que quieran entenderlo intuitivamente:
Interfaz
Aquí hay una interfaz con un método:
Entonces, cualquier tipo que tenga un
Run()
método satisface la interfaz Runner:Aunque el tipo de programa también tiene un método Stop, todavía satisface la interfaz Runner porque todo lo que se necesita es tener todos los métodos de una interfaz para satisfacerla.
Por lo tanto, tiene un método Run y satisface la interfaz Runner.
Interfaz vacía
Aquí hay una interfaz vacía con nombre sin ningún método:
Entonces, cualquier tipo satisface esta interfaz. Porque no se necesita ningún método para satisfacer esta interfaz. Por ejemplo:
Pero, ¿el tipo de programa anterior lo satisface? Si:
interfaz {} es igual a la interfaz vacía anterior.
Como puede ver, no tiene nada de misterioso, pero es muy fácil abusar de él. Manténgase alejado de él tanto como pueda.
https://play.golang.org/p/A-vwTddWJ7G
fuente
type Runner interface
no se usa en el ejemplo Go playground.De las especificaciones de Golang :
Los conceptos para graps son:
T
tiene 3 métodos:A
,B
,C
.T_interface = (A, B, C)
MyInterface = (A, )
MyInterface
deben estar contenidos dentroT_interface
Puede deducir que todos los "tipos de interfaz" de todos los tipos son un superconjunto de la interfaz vacía.
fuente
Un ejemplo que extiende la excelente respuesta de @VonC y el comentario de @ NickCraig-Wood.
interface{}
puede apuntar a cualquier cosa y necesita una aserción de conversión / tipo para usarla.i
es una variable de una interfaz vacía con un valorcat("Fish")
. Es legal crear un valor de método a partir de un valor de tipo de interfaz. Ver https://golang.org/ref/spec#Interface_types .Un interruptor de tipo confirma
i
que el tipo de interfaz escat("Fish")
. Ver https://golang.org/doc/effective_go.html#type_switch .i
luego se reasigna adog("Bone")
. Un interruptor de tipo confirma quei
el tipo de interfaz ha cambiado adog("Bone")
.También puede pedirle al compilador que verifique que el tipo
T
implementa la interfazI
al intentar una asignación:var _ I = T{}
. Ver https://golang.org/doc/faq#guarantee_satisfies_interface y https://stackoverflow.com/a/60663003/12817546 .Todos los tipos implementan la interfaz vacía
interface{}
. Ver https://talks.golang.org/2012/goforc.slide#44 y https://golang.org/ref/spec#Interface_types . En este ejemplo,i
se reasigna, esta vez a una cadena "4.3".i
luego se asigna a una nueva variable de cadenas
coni.(string)
antess
se convierte a un tipo float64f
usandostrconv
. Finalmentef
se convierte an
un tipo int igual a 4. Vea ¿Cuál es la diferencia entre conversión de tipo y aserción de tipo?Los mapas y sectores incorporados de Go, más la capacidad de usar la interfaz vacía para construir contenedores (con unboxing explícito) significan que en muchos casos es posible escribir código que haga lo que los genéricos permitirían, si no es así. Ver https://golang.org/doc/faq#generics .
fuente