Eu sou novo em interfaces e tentando fazer solicitação SOAP pelo github
Eu não entendo o significado de
Msg interface{}
neste código:
type Envelope struct {
Body `xml:"soap:"`
}
type Body struct {
Msg interface{}
}
Eu observei a mesma sintaxe em
fmt.Println
mas não entendo o que está sendo alcançado por
interface{}
interface{}
é mais ou menos o equivalentevoid *
em C. Ele pode apontar para qualquer coisa e você precisa de uma asserção de tipo / conversão para usá-lo.Respostas:
Você pode consultar o artigo " Como usar interfaces no Go " (com base na " Descrição de interfaces de Russ Cox "):
(Isso é o que
Msg
representa na sua pergunta: qualquer valor)Adendo: Este é o artigo de Russ bastante completo sobre uma estrutura de interface:
fonte
interface{}
significa que você pode colocar valor de qualquer tipo, incluindo seu próprio tipo personalizado. Todos os tipos no Go atendem a uma interface vazia (interface{}
é uma interface vazia).No seu exemplo, o campo Msg pode ter valor de qualquer tipo.
Exemplo:
Go Playground
fonte
É chamada de interface vazia e é implementada por todos os tipos, o que significa que você pode colocar qualquer coisa no
Msg
campo.Exemplo:
Essa é a extensão lógica do fato de um tipo implementar uma interface assim que tiver todos os métodos da interface.
fonte
Já existem boas respostas aqui. Deixe-me adicionar o meu também para outras pessoas que desejam entendê-lo intuitivamente:
Interface
Aqui está uma interface com um método:
Portanto, qualquer tipo que tenha um
Run()
método satisfaz a interface do Runner:Embora o tipo de programa também tenha um método Stop, ele ainda satisfaz a interface do Runner, pois tudo o que é necessário é ter todos os métodos de uma interface para satisfazê-lo.
Portanto, ele possui um método Run e satisfaz a interface Runner.
Interface vazia
Aqui está uma interface vazia nomeada sem nenhum método:
Portanto, qualquer tipo satisfaz essa interface. Porque, nenhum método é necessário para satisfazer essa interface. Por exemplo:
Mas, o tipo de programa acima o satisfaz? Sim:
interface {} é igual à interface vazia acima.
Como você vê, não há nada de misterioso nisso, mas é muito fácil abusar. Fique longe disso o máximo que puder.
https://play.golang.org/p/A-vwTddWJ7G
fonte
type Runner interface
não é usado no exemplo do playground Go.Das especificações de Golang :
Os conceitos para graps são:
T
tem 3 métodos:A
,B
,C
.T_interface = (A, B, C)
MyInterface = (A, )
MyInterface
devem estar contidos dentroT_interface
Você pode deduzir que todos os "tipos de interface" de todos os tipos são um superconjunto da interface vazia.
fonte
Um exemplo que amplia a excelente resposta de @VonC e o comentário de @ NickCraig-Wood.
interface{}
pode apontar para qualquer coisa e você precisa de uma declaração de elenco / tipo para usá-lo.i
é uma variável de uma interface com um valor vaziocat("Fish")
. É legal criar um valor de método a partir de um valor do tipo de interface. Consulte https://golang.org/ref/spec#Interface_types .Uma opção de tipo confirma que o
i
tipo de interface écat("Fish")
. Consulte https://golang.org/doc/effective_go.html#type_switch .i
é reatribuído paradog("Bone")
. Uma opção de tipo confirma quei
o tipo de interface foi alterado paradog("Bone")
.Você também pode pedir o compilador para verificar se o tipo
T
implementa a interfaceI
ao tentar uma atribuição:var _ I = T{}
. Consulte https://golang.org/doc/faq#guarantee_satisfies_interface e https://stackoverflow.com/a/60663003/12817546 .Todos os tipos implementam a interface vazia
interface{}
. Consulte https://talks.golang.org/2012/goforc.slide#44 e https://golang.org/ref/spec#Interface_types . Neste exemplo,i
é reatribuído, desta vez para uma string "4.3".i
é então atribuído a uma nova variável de cadeias
comi.(string)
antess
é convertido em um tipo float64f
usandostrconv
. Finalmente,f
é convertido emn
um tipo int igual a 4. Consulte Qual é a diferença entre conversão e asserção de tipo?Os mapas e fatias integrados da Go, além da capacidade de usar a interface vazia para construir contêineres (com unboxing explícito), significa que em muitos casos é possível escrever um código que faça o que os genéricos permitiriam, se menos suavemente. Veja https://golang.org/doc/faq#generics .
fonte