متدها (Methods)
متدهای Go با value receiver و pointer receiver و تفاوت مهم آنها.
متد چیست؟
متد تابعی است که به یک نوع مشخص متصل است — مثل توابع کلاس در زبانهای دیگر:
type Rectangle struct {
Width, Height float64
}
// متد با receiver
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
rect := Rectangle{Width: 5, Height: 3}
fmt.Println(rect.Area()) ← 15
Receiver چیست؟
پارامتر ویژه بین func و نام متد — مثل this یا self در زبانهای دیگر:
func (r Rectangle) Area() float64 {
// ↑ receiver: متد روی Rectangle کار میکند
return r.Width * r.Height
}
Value Receiver در مقابل Pointer Receiver
Value Receiver — کپی میگیرد
func (r Rectangle) Scale(factor float64) {
r.Width *= factor ← روی کپی کار میکند!
r.Height *= factor
}
rect := Rectangle{5, 3}
rect.Scale(2)
fmt.Println(rect.Width) ← 5 (تغییر نکرد!)
Pointer Receiver — روی اصل کار میکند
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor ← روی خود شی تغییر میدهد
r.Height *= factor
}
rect := Rectangle{5, 3}
rect.Scale(2) ← Go خودش &rect میفرستد
fmt.Println(rect.Width) ← 10 ✓
کدام را انتخاب کنیم؟
| وضعیت | Receiver |
|---|---|
| فقط خواندن فیلدها | Value (r) |
| تغییر فیلدها | Pointer (*r) |
| struct بزرگ (پرهزینه کپی) | Pointer |
| struct کوچک و فقطخواندنی | Value |
قانون مهم: اگر یکی از متدهای یک نوع Pointer Receiver دارد، همه متدها Pointer باشند — سازگاری!
متد روی هر نوعی
حتی روی انواع پایه (با type جدید):
type Celsius float64
func (c Celsius) ToFahrenheit() float64 {
return float64(c)*9/5 + 32
}
temp := Celsius(25)
fmt.Println(temp.ToFahrenheit()) ← 77
متد String() — نمایش سفارشی
func (p Person) String() string {
return fmt.Sprintf("%s (%d سال)", p.Name, p.Age)
}
p := Person{"علی", 25}
fmt.Println(p) ← علی (۲۵ سال)
این مبحث بخشی از دوره آموزش کامل گو است.