Интересно, что в языке Go приёмники тоже можно указывать двояко. Как указатели и как значения. Но при указании по значению нельзя изменять данные в приёмнике.
Честно говоря, я даже не знал, что приёмник может быть VAR-параметром в Обероне, пока не прочитал соответствующее место в описании Go и не стал проверять. VAR-параметров в Go нет, а только указатели. Оформляются как обероновские, но вместо «POINTER TO» пишется сишная звёздочка (а порядок лексем обероновский).
Код:
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := &Vertex{3, 4}
fmt.Printf("Before scaling: %+v, Abs: %v\n", v, v.Abs())
v.Scale(5)
fmt.Printf("After scaling: %+v, Abs: %v\n", v, v.Abs())
}
Вот как они это описывают:
Цитата:
Вы можете объявлять методы, где в качестве получателей выступают указатели.
Это означает, что получатель объявлен как `*T` для некоторого типа `T`.
(И еще, `T` не может быть указателем сам по себе, как, например, `*int`.)
Например, метод `Scale` в данном примере объявлен для `*Vertex`.
Методы с получателями-указателями могут модифицировать значение, на которое
указывает получатель (как делает `Scale` в данном примере).
Т.к. методам часто необходимо модифицировать получателя, то
использование указателей более частая практика, чем получатели как значения.
Попробуйте убрать `*` из объявления функции `Scale` на строке 16
и понаблюдайте, как изменяется поведение программы.
При использовании получателя-значения, метод `Scale` работает с копией оригинального
значения `Vertex`.
(Это такое же поведение, как и для любого другого аргумента функции.)
Метод `Scale` должен иметь указатель на получателя для того, чтобы изменить значение `Vertex`,
объявленное в функции `main`.