Я просто работаю над Go tour, и я смущен насчет указателей и интерфейсов. Почему этот код Go не компилируется?
package main
type Interface interface {}
type Struct struct {}
func main() {
var ps *Struct
var pi *Interface
pi = ps
_, _ = pi, ps
}
то есть. если Struct
является Interface
, почему бы не *Struct
быть *Interface
?
Сообщение об ошибке, которое я получаю:
prog.go:10: cannot use ps (type *Struct) as type *Interface in assignment:
*Interface is pointer to interface, not interface
Ответ 1
Когда у вас есть структура, реализующая интерфейс, указатель на эту структуру автоматически реализует этот интерфейс. Вот почему у вас никогда не было *SomeInterface
в прототипе функций, поскольку это ничего не добавит к SomeInterface
, и вам не нужен такой тип в объявлении переменной (см. этот связанный вопрос).
Значение интерфейса не является значением конкретной структуры (поскольку оно имеет размер переменной, это было бы невозможно), но это своего рода указатель (точнее указатель на структуру и указатель к типу). Russ Cox описывает это как здесь:
Значения интерфейса представляются в виде пары из двух слов, указывающей указатель к информации о типе, хранящемся в интерфейсе, и указателе на связанные данные.
![enter image description here]()
Вот почему Interface
, а не *Interface
- правильный тип, чтобы удерживать указатель на реализацию структуры Interface
.
Поэтому вы должны просто использовать
var pi Interface
Ответ 2
Возможно, это вы имели в виду:
package main
type Interface interface{}
type Struct struct{}
func main() {
var ps *Struct
var pi *Interface
pi = new(Interface)
*pi = ps
_, _ = pi, ps
}
Скомпилирует OK. См. Также здесь.