Методы структур
Получатели-значения и получатели-указатели
«Методы структур» — бесплатный урок Go Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Что такое метод?
Метод — это функция с аргументом-получателем. Получатель находится между ключевым словом func и именем метода, связывая функцию с типом.
Получатель-значение
Получатель-значение получает копию структуры. Используйте его, если методу не нужно изменять состояние:
package main
import "fmt"
type Circle struct{ Radius float64 }
func (c Circle) Area() float64 {
return 3.14159 * c.Radius * c.Radius
}
func main() {
c := Circle{Radius: 5}
fmt.Printf("%.2f\n", c.Area()) // 78.54
}Получатель-указатель
Получатель-указатель позволяет методу изменять структуру. Он эффективнее для больших структур:
package main
import "fmt"
type Counter struct{ N int }
func (c *Counter) Increment() { c.N++ }
func (c *Counter) Reset() { c.N = 0 }
func main() {
c := Counter{}
c.Increment(); c.Increment()
fmt.Println(c.N) // 2
c.Reset()
fmt.Println(c.N) // 0
}Когда использовать получатели-указатели
Используйте получатели-указатели, когда:
- Методу нужно изменить получателя
- Структура большая (это позволяет избежать копирования)
- Нужно обеспечить единообразие: если у какого-либо метода получатель-указатель, таким должен быть получатель у всех методов
Используйте получатели-значения, если структура небольшая и метод только читает данные.
Выражения и значения методов
Методы можно использовать как полноценные значения:
package main
import "fmt"
type Adder struct{ Base int }
func (a Adder) Add(n int) int { return a.Base + n }
func main() {
a := Adder{Base: 10}
fn := a.Add // method value — bound to a
fmt.Println(fn(5)) // 15
}Методы для типов, не являющихся структурами
Методы можно определять для любого именованного типа в том же пакете, а не только для структур:
package main
import "fmt"
type Celsius float64
func (c Celsius) ToFahrenheit() float64 {
return float64(c)*9/5 + 32
}
func main() {
t := Celsius(100)
fmt.Println(t.ToFahrenheit()) // 212
}Автоматическое разыменование указателей
Go автоматически получает адрес или разыменовывает указатель при вызове методов. Не нужно вручную писать (&c).Method():
package main
import "fmt"
type Box struct{ Val int }
func (b *Box) Double() { b.Val *= 2 }
func main() {
b := Box{Val: 5}
b.Double() // Go auto-takes address
fmt.Println(b.Val) // 10
}Цепочки методов
Возвращайте указатель на получатель, чтобы включить цепочки методов (шаблон построителя):
package main
import "fmt"
type Builder struct{ result string }
func (b *Builder) Add(s string) *Builder {
b.result += s
return b
}
func (b *Builder) Build() string { return b.result }
func main() {
s := (&Builder{}).Add("Hello").Add(", ").Add("World").Build()
fmt.Println(s)
}Строковый метод (fmt.Stringer)
Реализуйте метод String() string, чтобы управлять способом вывода типа:
package main
import "fmt"
type Point struct{ X, Y int }
func (p Point) String() string {
return fmt.Sprintf("(%d, %d)", p.X, p.Y)
}
func main() {
p := Point{3, 4}
fmt.Println(p) // (3, 4)
}Получатели-указатели nil
Метод с получателем-указателем можно вызвать для указателя nil — это удобно для поведения по умолчанию:
package main
import "fmt"
type Node struct{ Val int }
func (n *Node) Value() int {
if n == nil { return 0 }
return n.Val
}
func main() {
var n *Node
fmt.Println(n.Value()) // 0
}Принцип единообразия
В стандартной библиотеке Go и идиоматичном Go все методы типа используют один и тот же вид получателя — либо все получатели-указатели, либо все получатели-значения. Смешивание приводит к трудноуловимым ошибкам при работе с интерфейсами.
Быстрая проверка
Какой тип получателя позволяет методу изменять поля структуры?
Повторение: методы
Основные выводы:
- У методов есть получатель между
funcи именем - Получатели-значения: только чтение, небольшие структуры
- Получатели-указатели: изменение данных, большие структуры, единообразие
- Go автоматически разыменовывает указатели — не нужно писать
(&v).Method() - Реализуйте
String() stringдля настраиваемого вывода
Задание для практики
Определите структуру BankAccount с полем Balance float64. Добавьте методы с получателем-указателем Deposit и Withdraw, а также метод с получателем-значением String().
Часто задаваемые вопросы
Урок «Методы структур» бесплатный?
Да — полный текст урока «Методы структур» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Методы структур»?
Получатели-значения и получатели-указатели Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Методы структур»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Определение и использование структур
- Методы структур
- Шаблоны конструкторов
- Анонимные структуры и композиция