Я новичок в интерфейсах и пытаюсь выполнить запрос SOAP через github
Я не понимаю смысла
Msg interface{}
в этом коде:
type Envelope struct {
Body `xml:"soap:"`
}
type Body struct {
Msg interface{}
}
Я наблюдал такой же синтаксис в
fmt.Println
но не понимаю, что достигается
interface{}
interface{}
более или менее эквивалентенvoid *
в C. Он может указывать на что угодно, и для его использования вам потребуется утверждение приведения / типа.Ответы:
Вы можете обратиться к статье « Как использовать интерфейсы в Go » (на основе « описания интерфейсов Рассом Коксом »):
(Это то, что
Msg
представляет в вашем вопросе: любое значение)Приложение: Это статья Расса, довольно полная о структуре интерфейса:
источник
interface{}
означает, что вы можете поместить значение любого типа, включая ваш собственный тип. Все типы в Go удовлетворяют пустому интерфейсу (interface{}
это пустой интерфейс).В вашем примере поле Msg может иметь значение любого типа.
Пример:
Go Playground
источник
Он называется пустым интерфейсом и реализуется всеми типами, что означает, что в
Msg
поле можно поместить что угодно .Пример :
Это логическое продолжение того факта, что тип реализует интерфейс, как только у него есть все методы интерфейса.
источник
Здесь уже есть хорошие ответы. Позвольте мне добавить и свое собственное для тех, кто хочет понять это интуитивно:
Интерфейс
Вот интерфейс с одним методом:
Итак, любой тип, у которого есть
Run()
метод, удовлетворяет интерфейсу Runner:Хотя тип Program также имеет метод Stop, он по-прежнему удовлетворяет интерфейсу Runner, потому что все, что нужно, - это иметь все методы интерфейса, чтобы удовлетворить его.
Итак, у него есть метод Run, и он удовлетворяет интерфейсу Runner.
Пустой интерфейс
Вот именованный пустой интерфейс без каких-либо методов:
Таким образом, любой тип удовлетворяет этому интерфейсу. Потому что для удовлетворения этого интерфейса не требуется никакого метода. Например:
Но удовлетворяет ли ему указанный выше тип программы? Да:
interface {} совпадает с пустым интерфейсом выше.
Как видите, в этом нет ничего загадочного, но злоупотребить им очень легко. Держитесь подальше от этого, насколько можете.
https://play.golang.org/p/A-vwTddWJ7G
источник
type Runner interface
используется в примере с игровой площадкой Go.Из спецификаций Golang :
Понятия, которые нужно понять:
T
имеет 3 метода:A
,B
,C
.T_interface = (A, B, C)
MyInterface = (A, )
MyInterface
, должны содержаться внутриT_interface
Вы можете сделать вывод, что все «типы интерфейса» всех типов являются надмножеством пустого интерфейса.
источник
Пример, расширяющий отличный ответ @VonC и комментарий @ NickCraig-Wood.
interface{}
может указывать на что угодно, и для его использования вам потребуется утверждение приведения / типа.i
- это переменная пустого интерфейса со значениемcat("Fish")
. Допустимо создание значения метода из значения типа интерфейса. См. Https://golang.org/ref/spec#Interface_types .Переключатель типа подтверждает, что
i
тип интерфейса естьcat("Fish")
. См. Https://golang.org/doc/effective_go.html#type_switch .i
затем переназначается наdog("Bone")
. Переключатель типа подтверждает, чтоi
тип интерфейса изменился наdog("Bone")
.Вы также можете попросить компилятор проверить , что тип
T
реализует интерфейсI
, попытавшись задание:var _ I = T{}
. См. Https://golang.org/doc/faq#guarantee_satisfies_interface и https://stackoverflow.com/a/60663003/12817546 .Все типы реализуют пустой интерфейс
interface{}
. См. Https://talks.golang.org/2012/goforc.slide#44 и https://golang.org/ref/spec#Interface_types . В этом примереi
переназначается, на этот раз строке «4.3».i
затем присваивается новой строковой переменной,s
аi.(string)
befores
преобразуется в тип float64f
с использованиемstrconv
. Наконецf
, преобразуется вn
тип int, равный 4. См. В чем разница между преобразованием типа и утверждением типа?Встроенные карты и срезы Go, а также возможность использовать пустой интерфейс для создания контейнеров (с явной распаковкой) означают, что во многих случаях можно написать код, который делает то, что позволяют дженерики, хотя и менее плавно. См. Https://golang.org/doc/faq#generics .
источник