مرکزی مواد پر جائیں
ماڈیول 5 · سبق 2 از 5کورس میں 22/50~14 min
ماڈیول اسباق (2/5)

طریقے: ویلیو بمقابلہ پوائنٹر ریسیور

Go میں ایک طریقہ ایک فنکشن ہے جس میں رسیور ہوتا ہے: ایک خاص پیرامیٹر func اور طریقہ کے نام کے درمیان اعلان کیا گیا، جو پابند کرتا ہے۔ ایک قسم کا طریقہ۔ کوئی کلاسز نہیں ہیں: طریقوں کی وضاحت کی جا سکتی ہے۔ موجودہ پیکیج میں اعلان کردہ کسی بھی نام کی قسم۔

نحو

Go
type Person struct {
    Name string
}

func (p Person) Greet() string {
    return "ciao " + p.Name
}

p := Person{Name: "Ada"}
fmt.Println(p.Greet())   // "ciao Ada"

وصول کنندہ p Person Greet کو Person کا طریقہ بناتا ہے۔ کے اندر طریقہ، p کسی دوسرے کی طرح ایک متغیر ہے۔

ویلیو ریسیور بمقابلہ پوائنٹر ریسیور

Go
// VALUE receiver: operates on a COPY of the value
func (p Person) NameUpper() string {
    return strings.ToUpper(p.Name)
}

// POINTER receiver: operates on the original value, can mutate it
func (p *Person) Rename(n string) {
    p.Name = n
}

پوائنٹر ریسیور کے ساتھ آپ رسیور میں ترمیم اور تبدیلیاں کرسکتے ہیں۔ طریقہ سے باہر نظر آتے ہیں۔ ایک قدر وصول کنندہ کے ساتھ آپ نہیں کر سکتے — آپ کریں گے۔ صرف مقامی کاپی میں ترمیم کریں۔

Go
p := Person{Name: "Ada"}
p.Rename("Grace")
fmt.Println(p.Name)   // "Grace" — change is visible

پوائنٹر ریسیور کب استعمال کریں۔

عملی اصول، ترجیح کے لحاظ سے:

  1. آپ کو رسیور میں ترمیم کرنی ہوگی → پوائنٹر ریسیور۔ لازمی۔
  2. ** ساخت بڑا ہے** (درجنوں فیلڈز، اندر کی صفیں) → پوائنٹر مہنگی کاپیوں سے بچنے کے لیے وصول کنندہ۔
  3. مستقل مزاجی: اگر ٹائپ پر کم از کم ایک طریقہ میں پوائنٹر ریسیور ہے تو استعمال کریں دوسروں کے لیے بھی ایک پوائنٹر وصول کرنے والا۔ کے لیے ایک انتہائی اہم کنونشن انٹرفیس (ماڈیول 6)۔
  4. چھوٹی، غیر متغیر، "قدر" کی اقسام (وقت، وقت، پیچیدہ نمبر، چھوٹے structs) → ویلیو ریسیور، زیادہ پڑھنے کے قابل۔

غیر ساختی اقسام پر طریقے

آپ اپنے پیکیج میں اعلان کردہ کسی بھی NAMED قسم پر طریقوں کی وضاحت کر سکتے ہیں:

Go
type Celsius float64

func (c Celsius) ToFahrenheit() float64 {
    return float64(c)*9/5 + 32
}

t := Celsius(20)
fmt.Println(t.ToFahrenheit())  // 68

آپ دوسرے پیکجوں کی اقسام پر ان کی وضاحت نہیں کر سکتے ہیں (جیسے int, string): آپ کو پہلے مقامی نام کی قسم بنائیں۔

اسے آزمائیں

ورزش#go.m5.l2.e1
کوششیں: 0لوڈ ہو رہا ہے…

'ciao <Name>' واپس کرنے والے شخص میں Greet() سٹرنگ طریقہ (ویلیو وصول کنندہ) شامل کریں۔

ایڈیٹر لوڈ ہو رہا ہے…
اشارہ دکھائیں۔

طریقہ کے نام سے پہلے قوسین میں وصول کنندہ۔

3 کوششوں کے بعد حل دستیاب ہے۔

ورزش#go.m5.l2.e2
کوششیں: 0لوڈ ہو رہا ہے…

POINTER وصول کنندہ کے ساتھ نام تبدیل کرنے کا طریقہ (n string) شامل کریں جو p.Name کو تبدیل کرتا ہے۔

ایڈیٹر لوڈ ہو رہا ہے…
اشارہ دکھائیں۔

پوائنٹر وصول کنندہ: `(p *Person)`۔

3 کوششوں کے بعد حل دستیاب ہے۔

Quiz#go.m5.l2.e3
تیار

آپ کو پوائنٹر ریسیور (p*T) کب استعمال کرنا چاہیے؟

Go
func (t ?T) M() { ... }
جواب کے اختیارات

Recap

  • طریقہ = وصول کنندہ کے ساتھ فنکشن: func (r T) Name(...) ... { ... }۔
  • ویلیو وصول کنندہ: ایک کاپی پر کام کرتا ہے۔ پوائنٹر وصول کنندہ: اصل پر کام کرتا ہے۔
  • گو کال سائٹ پر T ↔ *T کی تبدیلی خود بخود انجام دیتا ہے۔
  • پوائنٹر وصول کنندہ جب: اتپریورتن + بڑی ساخت + قسم کے دیگر طریقوں کے ساتھ مستقل مزاجی۔
  • ایک ہی قسم پر کبھی بھی ویلیو اور پوائنٹر ریسیورز کو مکس نہ کریں۔
  • طریقے موجودہ پیکج میں NAMED اقسام پر چلتے ہیں (بشمول غیر ساختہ)۔