#go #methods #go-interface
#Вперед #методы #go-интерфейс
Вопрос:
Вот ссылка на код и описание, которые я просматривал: https://tour.golang.org/methods/11
Я меняю метод M типа * T на T, который изменяется с приемника указателя на приемник значения, как показано ниже.
package main
import (
"fmt"
"math"
)
type I interface {
M()
}
type T struct {
S string
}
func (t T) M() {
fmt.Println(t.S)
}
type F float64
func (f F) M() {
fmt.Println(f)
}
func main() {
var i I
i = amp;T{"Hello"}
describe(i)
i.M()
i = F(math.Pi)
describe(i)
i.M()
}
func describe(i I) {
fmt.Printf("(%v, %T)n", i, i)
}
Однако приведенное выше изменение дало мне тот же результат, поскольку оно по-прежнему было получателем указателя.
(amp;{Hello}, *main.T)
Hello
(3.141592653589793, main.F)
3.141592653589793
Я не уверен, что правильно понял эту концепцию. Насколько я понимаю, поскольку переменной интерфейса, которую я получил, присваивается указатель на экземпляр struct T, типом этой переменной интерфейса должен быть указатель на struct T, а поскольку указатель на struct T не реализует метод M, это вызовет панику.
Ответ №1:
Набор методов соответствующего типа указателя
*T
является набором всех методов, объявленных с помощью receiver*T
илиT
(то есть, он также содержит набор методовT
).[…] Набор методов типа определяет интерфейсы, которые этот тип реализует, и методы, которые могут быть вызваны с использованием приемника этого типа.
Таким образом, все методы, которые вы объявляете с помощью value receiver, также будут принадлежать набору методов соответствующего типа указателя, и, таким образом, все интерфейсы, реализуемые типом без указателя, также будут реализованы типом указателя (и, возможно, больше).
Ответ №2:
В Go есть несколько ярлыков. Например:
a.Method()
a.Field
это то же самое, что
(*a).Method()
(*a).Field
аналогично приведенной здесь концепции https://tour.golang.org/moretypes/4