Почему не назначается новый ключи в итнерфейс?

В Go не возможно назначить новые ключи для интерфейсов. Это связано с тем, что интерфейсы в Go определены как набор методов, которые должны быть реализованы в типе, чтобы он удовлетворял этому интерфейсу.

Перед тем как объяснить почему, давайте рассмотрим пример:

type Animal interface {
    MakeSound()
}

type Dog struct {
    Name string
}

func (d Dog) MakeSound() {
    fmt.Println("Woof!")
}

func main() {
    var animal Animal = Dog{Name: "Buddy"}
    animal.MakeSound()
}

В этом примере, у нас есть интерфейс Animal с единственным методом MakeSound(). Мы также имеем структуру Dog, которая реализует этот метод.

В функции main() мы создаем переменную animal типа Animal и присваиваем ей значение типа Dog. После этого мы вызываем метод MakeSound() на переменной animal и получаем "Woof!" в консоли.

Теперь представим ситуацию, в которой мы хотим расширить интерфейс Animal, добавив новый метод Move(), который будет задавать движение животного. Мы могли бы попытаться сделать это следующим образом:

type Animal interface {
    MakeSound()
    Move()
}

func (d Dog) Move() {
    fmt.Println("Running")
}

Однако, если мы попытаемся добавить новый метод Move() в описанном выше коде, мы получим ошибку компиляции, с сообщением:

cannot define new methods on non-local type Dog

Проблема заключается в том, что для добавления нового метода в интерфейс необходимо изменить определение самого типа. Поскольку тип Dog является типом из сторонней библиотеки или модуля, мы не можем изменить его определение, чтобы добавить новый метод.

Вместо этого, мы можем создать новый интерфейс с требуемыми методами и реализовать его в типе Dog:

type Animal interface {
    MakeSound()
}

type Movable interface {
    Move()
}

type Dog struct {
    Name string
}

func (d Dog) MakeSound() {
    fmt.Println("Woof!")
}

func (d Dog) Move() {
    fmt.Println("Running")
}

В этом примере, мы создаем новый интерфейс Movable с методом Move(). Затем мы реализуем этот метод в структуре Dog. Теперь мы можем использовать и интерфейс Animal, и интерфейс Movable, чтобы получить поведение в соответствии с нашими потребностями:

func main() {
    var animal Animal = Dog{Name: "Buddy"}
    animal.MakeSound()

    var movable Movable = Dog{Name: "Rover"}
    movable.Move()
}

Таким образом, хотя в Go нет возможности добавить новые методы к уже существующему интерфейсу, мы можем создавать новые интерфейсы и имплементировать их в нужных структурах, чтобы расширить функциональность наших типов.