Указатели¶
TL;DR¶
&x— взять адрес переменной x.*p— разыменовать (получить значение).- Передача в функции по значению; для модификации передавай
*T. - nil-разыменование = runtime panic.
Зачем нужны указатели¶
- Модифицировать аргумент функции.
- Не копировать большую структуру.
- Optional поля (например,
*time.Timeдля опциональной даты).
Минимальный пример¶
Receiver: pointer vs value¶
type Counter struct{ n int }
func (c Counter) IncVal() { c.n++ } // изменения теряются
func (c *Counter) IncPtr() { c.n++ } // модифицирует исходный
Правило: используй pointer receiver, если метод меняет state, или если структура большая и копировать дорого.
Гочча — typed nil¶
type MyError struct{}
func (e *MyError) Error() string { return "" }
func mayFail() error {
var p *MyError
return p // вернёт *MyError(nil), но интерфейс != nil
}
err := mayFail()
fmt.Println(err == nil) // false
Объяснение: интерфейс хранит (type, value). Тут type = *MyError (≠ nil),
value = nil. err == nil true только когда оба = nil.
📖 Подробнее в справочнике задач на 100%.