Задать вопрос
@sorax_nk

Почему в одном случае интерфейс реализуется, а во втором — нет?

Здравствуйте, недавно начал изучать Go и столкнулся с такой проблемой. Первая структура имеет метод с value receiver, а вторая структура с point receiver. Обе структуры реализуют интерфейс. В первом случае я присваиваю интерфейсу структуру по значению и по ссылке. Ошибки почему-то не выдает, хотя метод первой структуры имеет рисивер на значение, а не на адрес. Но во втором случае, если я пытаюсь передать вторую структуру не по ссылке, а по значению, то возникает ошибка, т.к интерфейс не реализуется. Сильно запутался и не могу понять, почему в первом случае интерфейс реализуется при передачи структуры и по значению, и по ссылке.
package main

import "fmt"

type ifRealization interface {
    init()
}
type firstStruct struct{}

func (f firstStruct) init() {
    fmt.Printf("Init; Type: %T Value: %v", f, f)
}

type secondStruct struct{}

func (f *secondStruct) init() {
    fmt.Printf("Init; Type: %T Value: %v", f, f)
}

func main() {
    var first ifRealization = firstStruct{}
    var second ifRealization = &firstStruct{} // Ошибки нет
    first.init()
    second.init()

    var f ifRealization = secondStruct{} //Type does not implement 'ifRealization' as the 'init' method has a pointer receiver
    var s ifRealization = &secondStruct{} //Ошибки нет
}
  • Вопрос задан
  • 207 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
@micronull
Go умеет самостоятельно разименовывать указатели при вызове метода.

Т.е. так как у нас по факту переменная `second` является указателем на структуру `firstStruct`, то мы должны были бы предварительно разименовать, перед вызовом метода `init`:
var second *firstStruct = &firstStruct{} 
(*second).init()

Но Go знает что это указатель и в синтаксисе можно производить вызов метода напрямую, а Go самостоятельно разименует указатель на структуру.
second.init()

У конструкции `&secondStruct{}` нет ошибки, так как сигнатура метода описывает работу с указателем на структуру:
func (f *secondStruct) init() {...}
Поэтому такая консрукция в данном случае не доступна: var f ifRealization = secondStruct{}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы