← Все этапы
03 · ДАННЫЕ И ТИПЫУрок 17 из 3323 минуты

Методы и получатели

Добавляем типам поведение и выбираем получатель по значению или указателю.

Поведение рядом с типом

Обычная функция отдельно принимает значение: move(point, dx). Метод привязывает функцию к именованному типу, и его вызывают через точку: point.move(dx). Тип перед точкой в объявлении называется получателем метода.

Получатель-значение, например (p point), получает копию структуры. Он подходит для вычислений и чтения, но изменение p не меняет исходную переменную. Получатель-указатель, например (p *point), работает с исходным объектом и позволяет менять его поля. Для адресуемой переменной Go автоматически подставляет адрес при вызове метода с указательным получателем.

Пример

package main

import "fmt"

type point struct {
	x int
	y int
}

func (p *point) move(dx, dy int) {
	p.x += dx
	p.y += dy
}

func (p point) manhattanDistance() int {
	return abs(p.x) + abs(p.y)
}

func abs(value int) int {
	if value < 0 {
		return -value
	}
	return value
}

func main() {
	point := point{x: 2, y: -3}
	point.move(4, 1)
	fmt.Printf("точка: (%d, %d), расстояние: %d\n", point.x, point.y, point.manhattanDistance())
}

После перемещения точка равна (6, -2), расстояние до начала координат по сумме модулей равно 8. Метод чтения получает копию, что безопасно, потому что он ничего не меняет.

Выбирай указательный получатель, когда методу нужно менять состояние или структура велика и копировать её нежелательно. Для одного типа обычно придерживаются одного стиля получателей, чтобы поведение было предсказуемым. Указательный получатель нельзя вызвать на значении, которое не имеет адреса, например на временном результате функции.

Практика

Попробуйте сами

Создай тип counter с полем value. Добавь метод add(step int) с указательным получателем и метод current() int с получателем-значением. Создай счётчик со значением 5, прибавь 3 и выведи результат вызовом current.

Проверка результата

Как понять, что получилось

Программа выводит 8. Метод add изменяет поле исходного счётчика через указатель, а current возвращает значение без изменения счётчика.

Методы и получатели | Go | WebSchool · Go