Почему я не могу назначить * Struct на * интерфейс?

Я просто работаю над 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. См. Также здесь.