متدها (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)   ← علی (۲۵ سال)

این مبحث بخشی از دوره آموزش کامل گو است.

ابزارهای مرتبط