type Person struct {
Name string
Age int
}
// Это метод структуры Person
func (p Person) Greet() string {
return "Hello, my name is " + p.Name
} func (receiver Type) MethodName(parameters) returnType {
// тело метода
} type Account struct {
Owner string
Balance float64
}
// Метод для получения информации о счёте
func (a Account) Info() string {
return fmt.Sprintf("Account owner: %s, Balance: %.2f", a.Owner, a.Balance)
}
// Метод для проверки, достаточно ли средств
func (a Account) HasEnoughMoney(amount float64) bool {
return a.Balance >= amount
} func main() {
acc := Account{
Owner: "Alice",
Balance: 1000.0,
}
fmt.Println(acc.Info()) // ← Account owner: Alice, Balance: 1000.00
fmt.Println(acc.HasEnoughMoney(500.0)) // ← true
fmt.Println(acc.HasEnoughMoney(1500.0)) // ← false
} type Counter struct {
Value int
}
// Метод с value receiver
func (c Counter) Increment() {
c.Value++ // ← Изменяется только копия!
}
func main() {
counter := Counter{Value: 0}
counter.Increment()
fmt.Println(counter.Value) // ← Выведет 0, не 1!
} type Rectangle struct {
Width float64
Height float64
}
// Value receiver подходит, так как мы только вычисляем значение
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Height)
} type Counter struct {
Value int
}
// Метод с pointer receiver
func (c *Counter) Increment() {
c.Value++ // ← Изменяется оригинал
}
func main() {
counter := Counter{Value: 0}
counter.Increment()
fmt.Println(counter.Value) // ← Выведет 1
} type Account struct {
Balance float64
}
func (a *Account) Deposit(amount float64) {
a.Balance += amount // ← Изменяет оригинал
}
func (a Account) GetBalance() float64 {
return a.Balance // ← Только читает
} type Counter struct {
Value int
}
func (c *Counter) Increment() {
c.Value++
}
func (c Counter) GetValue() int {
return c.Value
}
func main() {
// Значение → указатель (для pointer receiver)
counter1 := Counter{Value: 5}
counter1.Increment() // ← Go автоматически преобразует в (&counter1).Increment()
// Указатель → значение (для value receiver)
counter2 := &Counter{Value: 10}
val := counter2.GetValue() // ← Go автоматически разыменовывает в (*counter2).GetValue()
fmt.Println(val) // ← 10
} func GetCounter() Counter {
return Counter{Value: 5}
}
func main() {
// Это не скомпилируется!
// GetCounter().Increment() // ← Ошибка: cannot take the address of GetCounter()
// Нужно сначала сохранить в переменную
c := GetCounter()
c.Increment() // ← Теперь работает
} type Temperature struct {
Celsius float64
}
func (t *Temperature) SetFahrenheit(f float64) {
t.Celsius = (f - 32) * 5 / 9
} type LargeData struct {
Data [1000000]int
// ... много других полей
}
// Pointer receiver избегает копирования миллиона чисел
func (ld *LargeData) Process() {
// обработка данных
} type User struct {
Name string
Email string
Age int
}
func (u *User) SetEmail(email string) {
u.Email = email // ← Изменяет структуру
}
// Для консистентности используем pointer receiver, хотя метод только читает
func (u *User) GetInfo() string {
return fmt.Sprintf("%s (%s), age: %d", u.Name, u.Email, u.Age)
} type account struct {
balance float64 // ← Неэкспортируемое поле
}
// Экспортируемый метод
func (a *account) Deposit(amount float64) {
if amount > 0 {
a.balance += amount
}
}
// Экспортируемый метод
func (a account) Balance() float64 {
return a.balance
} type Celsius float64
type Fahrenheit float64
func (c Celsius) ToFahrenheit() Fahrenheit {
return Fahrenheit(c*9/5 + 32)
}
func (f Fahrenheit) ToCelsius() Celsius {
return Celsius((f - 32) * 5 / 9)
}
func main() {
temp := Celsius(20.0)
fmt.Printf("%.1f°C = %.1f°F\n", temp, temp.ToFahrenheit()) // ← 20.0°C = 68.0°F
} // Это не скомпилируется!
// func (s string) Reverse() string { // ← Ошибка: cannot define new methods on non-local type string
// // ...
// }
// Нужно создать свой тип
type MyString string
func (s MyString) Reverse() string {
runes := []rune(s)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
} type Tree struct {
Value int
Left *Tree
Right *Tree
}
// Метод работает корректно даже для nil
func (t *Tree) Sum() int {
if t == nil {
return 0
}
return t.Value + t.Left.Sum() + t.Right.Sum()
}
func main() {
tree := &Tree{
Value: 1,
Left: &Tree{Value: 2},
Right: nil, // ← Right равен nil
}
fmt.Println(tree.Sum()) // ← 3 (1 + 2 + 0)
}