ప్రధాన కంటెంట్‌కు వెళ్లండి
మాడ్యూల్ 5 · 5లో పాఠం 2కోర్సులో 22/50~14 min
మాడ్యూల్ పాఠాలు (2/5)

పద్ధతులు: విలువ vs పాయింటర్ రిసీవర్

గోలో పద్ధతి అనేది రిసీవర్తో కూడిన ఫంక్షన్: ప్రత్యేకం పరామితి 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 అనేది ఇతర వేరియబుల్.

విలువ రిసీవర్ vs పాయింటర్ రిసీవర్

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. చిన్న, మార్పులేని, "విలువ" రకాలు (సమయం. సమయం, సంక్లిష్ట సంఖ్యలు, చిన్నవి స్ట్రక్ట్స్) → విలువ రిసీవర్, మరింత చదవగలిగేది.

నాన్-స్ట్రక్ట్ రకాలపై పద్ధతులు

మీ ప్యాకేజీలో ప్రకటించబడిన ఏదైనా 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>'ని అందించే వ్యక్తికి గ్రీట్() స్ట్రింగ్ పద్ధతిని (విలువ రిసీవర్) జోడించండి.

ఎడిటర్ లోడ్ అవుతోంది…
సూచనను చూపించు

పద్ధతి పేరుకు ముందు కుండలీకరణాల్లో రిసీవర్.

3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది

వ్యాయామం#go.m5.l2.e2
ప్రయత్నాలు: 0లోడ్ అవుతోంది...

p.Nameని మార్చే POINTER రిసీవర్‌తో Rename(n స్ట్రింగ్) పద్ధతిని జోడించండి.

ఎడిటర్ లోడ్ అవుతోంది…
సూచనను చూపించు

పాయింటర్ రిసీవర్: `(p *వ్యక్తి)`.

3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది

Quiz#go.m5.l2.e3
సిద్ధంగా ఉంది

మీరు పాయింటర్ రిసీవర్ (p *T)ని ఎప్పుడు ఉపయోగించాలి?

Go
func (t ?T) M() { ... }
సమాధాన ఎంపికలు

రీక్యాప్

  • పద్ధతి = రిసీవర్‌తో ఫంక్షన్: func (r T) Name(...) ... { ... }.
  • విలువ రిసీవర్: కాపీపై పనిచేస్తుంది; పాయింటర్ రిసీవర్: అసలైనదానిపై పనిచేస్తుంది.
  • Go కాల్ సైట్‌లో స్వయంచాలకంగా T ↔ *T మార్పిడిని నిర్వహిస్తుంది.
  • పాయింటర్ రిసీవర్ ఎప్పుడు: మ్యుటేషన్ + పెద్ద నిర్మాణం + రకం ఇతర పద్ధతులతో స్థిరత్వం.
  • విలువ మరియు పాయింటర్ రిసీవర్‌లను ఒకే రకంలో ఎప్పుడూ కలపవద్దు.
  • ప్రస్తుత ప్యాకేజీలో (నాన్-స్ట్రక్ట్‌తో సహా) NAMED రకాలపై పద్ధతులు కొనసాగుతాయి.