Если выражение x имеет статический тип T и M находится в наборе методов типа T, x.M называется значением метода. Значение метода x.M - это значение функции, которое можно вызывать с теми же аргументами, что и вызов метода x.M. Выражение x вычисляется и сохраняется во время оценки значения метода; сохраненная копия затем используется в качестве получателя в любых вызовах, которые могут быть выполнены позже.
Тип T может быть интерфейсным или неинтерфейсным типом.
Рассмотрим тип структуры T с двумя методами: Mv, получатель которого имеет тип T, и Mp, получатель которого имеет тип *T.
type T struct {
a int
}
func (tv T) Mv(a int) int { return 0 } // получатель значение (value receiver)
func (tp *T) Mp(f float32) float32 { return 1 } // получатель указатель (pointer receiver)
var t T
var pt *T
func makeT() T
Выражение
t.Mv
дает значение функции типа
func(int) int
Следующие два вызова эквивалентны:
t.Mv(7)
f := t.Mv; f(7)
Аналогично, выражение
pt.Mp
дает значение функции типа
func(float32) float32
Как и в случае селекторов, ссылка на неинтерфейсный метод с получателем значения, использующим указатель, автоматически разыменует этот указатель: pt.Mv эквивалентен (*pt).Mv.
Как и в случае вызовов методов, ссылка на неинтерфейсный метод с получателем указателя, использующим адресуемое значение, автоматически получит адрес этого значения: t.Mp эквивалентно (&t).Mp.
f := t.Mv; f(7) // то же что и t.Mv(7)
f := pt.Mp; f(7) // то же что и pt.Mp(7)
f := pt.Mv; f(7) // то же что и (*pt).Mv(7)
f := t.Mp; f(7) // то же что и (&t).Mp(7)
f := makeT().Mp // недопустимо: результат makeT() не адресуем
Хотя в приведенных выше примерах используются неинтерфейсные типы, также допустимо создавать значение метода из значения интерфейсного типа.
var i interface { M(int) } = myVal
f := i.M; f(7) // то же что и i.M(7)
Читайте также:
- Спецификация Go: объявления методов
- Спецификация Go: литералы функций
- Спецификация Go: выражения методов (method expressions)
Комментариев нет:
Отправить комментарий