پرش به محتوا

زبان برنامه‌نویسی گو/متدها و دریافت‌کننده‌ها

ویکی‎کتاب، کتابخانهٔ آزاد

متدها و دریافت‌کننده‌ها در Go

[ویرایش]

در زبان برنامه‌نویسی Go علاوه بر توابع عادی، قابلیتی به نام متد (Method) وجود دارد. متدها مشابه توابع هستند اما با یک تفاوت مهم: آن‌ها به یک نوع (Type) خاص مرتبط می‌شوند. این ارتباط از طریق چیزی به نام دریافت‌کننده (Receiver) برقرار می‌گردد.

تعریف متد

[ویرایش]

یک متد در Go در واقع یک تابع است که یک دریافت‌کننده دارد. دریافت‌کننده مشخص می‌کند که این متد متعلق به چه نوعی است.

package main

import "fmt"

// تعریف یک نوع سفارشی
type Person struct {
    name string
    age  int
}

// تعریف متد برای نوع Person
func (p Person) Greet() {
    fmt.Println("سلام، من", p.name, "هستم و", p.age, "سال دارم.")
}

func main() {
    p := Person{name: "علی", age: 30}
    p.Greet() // فراخوانی متد
}

دریافت‌کننده (Receiver)

[ویرایش]

دریافت‌کننده به دو صورت تعریف می‌شود:

  • دریافت‌کنندهٔ مقداری (Value Receiver)
  • دریافت‌کنندهٔ اشاره‌گری (Pointer Receiver)

دریافت‌کنندهٔ مقداری

[ویرایش]

اگر دریافت‌کننده از نوع مقداری باشد، متد روی یک کپی از مقدار اصلی عمل می‌کند.

package main

import "fmt"

type Rectangle struct {
    width, height int
}

// متد با دریافت‌کننده مقداری
func (r Rectangle) Area() int {
    return r.width * r.height
}

func main() {
    rect := Rectangle{width: 10, height: 5}
    fmt.Println("مساحت:", rect.Area())
}

در این مثال، متد `Area` فقط داده‌ها را می‌خواند و تغییری ایجاد نمی‌کند، پس دریافت‌کنندهٔ مقداری کافی است.

دریافت‌کنندهٔ اشاره‌گری

[ویرایش]

اگر دریافت‌کننده از نوع اشاره‌گر باشد، متد روی خود شیء اصلی عمل می‌کند نه روی یک کپی. این روش زمانی کاربرد دارد که بخواهیم وضعیت شیء را تغییر دهیم یا از کپی غیرضروری جلوگیری کنیم.

package main

import "fmt"

type Counter struct {
    value int
}

// متد با دریافت‌کننده اشاره‌گری
func (c *Counter) Increment() {
    c.value++
}

func main() {
    c := Counter{}
    c.Increment()
    fmt.Println("مقدار شمارنده:", c.value)
}

اگر در این مثال از دریافت‌کنندهٔ مقداری استفاده می‌کردیم، تغییرات در نسخهٔ کپی انجام می‌شد و مقدار اصلی تغییر نمی‌کرد.

انتخاب بین Value Receiver و Pointer Receiver

[ویرایش]
  • اگر متد فقط داده‌ها را می‌خواند و نیازی به تغییر ندارد → مقداری
  • اگر متد نیاز به تغییر مقادیر دارد یا نوع داده بزرگ است → اشاره‌گری

متدها در انواع غیرساختاری

[ویرایش]

در Go حتی می‌توان برای انواع سفارشی غیرساختاری (مانند نوع عددی) هم متد تعریف کرد.

package main

import "fmt"

type MyInt int

// متدی برای نوع عددی سفارشی
func (m MyInt) IsEven() bool {
    return m%2 == 0
}

func main() {
    var n MyInt = 10
    fmt.Println(n, "زوج است؟", n.IsEven())
}

مقایسه متدها و توابع

[ویرایش]
  • توابع مستقل تعریف می‌شوند و به هیچ نوعی تعلق ندارند.
  • متدها همیشه یک دریافت‌کننده دارند و به نوع خاصی متصل هستند.

جمع‌بندی

[ویرایش]
  • متدها در Go در واقع توابعی با دریافت‌کننده هستند.
  • دریافت‌کننده می‌تواند مقداری یا اشاره‌گری باشد.
  • دریافت‌کنندهٔ مقداری برای خواندن داده‌ها مناسب است، در حالی‌که دریافت‌کنندهٔ اشاره‌گری برای تغییر وضعیت شیء استفاده می‌شود.
  • امکان تعریف متد برای هر نوع سفارشی (ساختارها، نوع‌های عددی و ...) وجود دارد.

این قابلیت به شما اجازه می‌دهد رفتارها را به انواع مختلف اضافه کنید و کدی تمیزتر و شیء‌گراتر بنویسید.