В последнем фрагменте кода реализован метод-приемник типа указателя.Это будет учитывать ситуацию, если вы хотите изменить значение получателя.
func (e *esc) GotU() {
e.i = 10
}
В вышеприведенном случае, так как вы передаете получатель типа указателя на метод, который реализует интерфейс.
type myintf interface {
GotU()
}
Поэтому вам нужно передать адрес структуры в TestFunc
.Это причина того, что вы получаете ошибку несоответствия типов, потому что вы передаете переменную типа esc
, в то время как вашему методу требуется переменная *esc
.
func main() {
var test esc
test.i = 9
TestFunc(&test)
fmt.Println(test.i)
}
Пример работы на Go Play *
В Golang есть два способа передать приемник метода.
func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct) valueMethod() { } // method on value
Для программистов, не привыкших к указателям, различие между этими двумя примерами может сбивать с толку, но ситуацияна самом деле очень просто.При определении метода для типа получатель (s в приведенных выше примерах) ведет себя точно так же, как если бы он был аргументом метода.Определить получатель как значение или как указатель - это один и тот же вопрос, а также, должен ли аргумент функции быть значением или указателем.Есть несколько соображений
Во-первых, и самое главное, должен ли метод модифицировать приемник?Если это так, получатель должен быть указателем.(Срезы и карты действуют как ссылки, поэтому их история немного более тонкая, но, например, чтобы изменить длину среза в методе, получатель должен оставаться указателем.) В приведенных выше примерах, если pointerMethod изменяет поляs, вызывающая сторона увидит эти изменения, но valueMethod вызывается с копией аргумента вызывающей стороны (это определение передачи значения), поэтому сделанные изменения будут невидимы для вызывающей стороны.