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

`కొత్త...` కన్స్ట్రక్టర్ నమూనా

Goకి constructor కీవర్డ్ లేదు. సమావేశం ఒక ** ఫ్యాక్టరీ ఫంక్షన్** సరిగ్గా ప్రారంభించబడిన విలువ లేదా పాయింటర్‌ని అందిస్తుంది. ద్వారా పేరు దీనిని సాధారణంగా NewT (లేదా NewXxx) అంటారు.

ఆధార నమూనా: NewT

Go
type User struct {
    Name string
    Age  int
}

func NewUser(name string, age int) *User {
    return &User{Name: name, Age: age}
}

u := NewUser("Ada", 36)
fmt.Println(u.Name)

ప్రత్యక్ష అక్షరార్థం &User{...}పై ప్రయోజనాలు:

  • మీరు సెంట్రలైజ్ ధ్రువీకరణ మరియు డిఫాల్ట్‌లు.
  • మీరు ఎగుమతి చేయని ఫీల్డ్‌లను కలిగి ఉండవచ్చు మరియు వాటిని కన్స్ట్రక్టర్ నుండి మాత్రమే నింపవచ్చు.
  • మీరు కాలర్‌లను విచ్ఛిన్నం చేయకుండా అమలును మార్చవచ్చు.

ధ్రువీకరణతో కన్స్ట్రక్టర్: (*T, ఎర్రర్)

ప్రారంభించడం విఫలమైనప్పుడు, (*T, error)ని తిరిగి ఇవ్వండి:

Go
import "errors"

func NewUser(name string, age int) (*User, error) {
    if name == "" {
        return nil, errors.New("nome obbligatorio")
    }
    if age < 0 {
        return nil, errors.New("eta non valida")
    }
    return &User{Name: name, Age: age}, nil
}

u, err := NewUser("Ada", 36)
if err != nil {
    // handle...
}

ఇది ఏ కన్స్ట్రక్టర్‌కైనా ఇడియోమాటిక్ నమూనా ముందస్తు షరతులు: db కనెక్షన్, ఫైల్ హ్యాండిల్, సర్వర్ కాన్ఫిగర్ మొదలైనవి.

బహుళ కన్స్ట్రక్టర్లు

మీరు నిర్మించడానికి బహుళ "మార్గాలు" కలిగి ఉంటే, వివరణాత్మక పేర్లను ఉపయోగించండి:

Go
func NewUser(name string) *User { ... }
func NewUserFromJSON(data []byte) (*User, error) { ... }
func NewAdmin() *User { ... }

గోలో ఓవర్‌లోడింగ్ లేదు: పేరు అస్పష్టంగా ఉంది.

ఫంక్షనల్ ఎంపికలు (అధునాతన సంగ్రహావలోకనం)

అనేక ఐచ్ఛిక పారామితులు ఉన్నప్పుడు, ఇడియోమాటిక్ నమూనా "ఫంక్షనల్ ఎంపికలు":

Go
type Option func(*Server)

func WithPort(p int) Option {
    return func(s *Server) { s.Port = p }
}

func WithTLS(cert, key string) Option {
    return func(s *Server) { s.Cert, s.Key = cert, key }
}

func NewServer(opts ...Option) *Server {
    s := &Server{Port: 8080} // default
    for _, opt := range opts {
        opt(s)
    }
    return s
}

s := NewServer(WithPort(9000), WithTLS("c.pem", "k.pem"))

ఇది లిటరల్ కంటే ఎక్కువ వెర్బోస్ అయితే చాలా ఐచ్ఛికంతో బాగా స్కేల్ అవుతుంది పరామితులు మరియు వెనుకకు అనుకూలతను సంరక్షిస్తుంది (కొత్త Option జోడించడం ఇప్పటికే ఉన్న కాలర్‌లను విచ్ఛిన్నం చేయదు).

మీకు కన్స్ట్రక్టర్ అవసరం లేనప్పుడు

రకం యొక్క సున్నా విలువ ఇప్పటికే ఉపయోగకరంగా ఉంటే, కాలర్‌ని ఉపయోగించనివ్వండి ప్రత్యక్ష సాహిత్యం. నియమానుగుణ ఉదాహరణ: sync.Mutexకి కన్స్ట్రక్టర్ లేదు, var m sync.Mutex ఇప్పటికే ఉపయోగించడానికి సిద్ధంగా ఉన్న మ్యూటెక్స్. bytes.Bufferకి అదే.

నియమం: "సున్నా విలువను ఉపయోగకరంగా చేయండి". మీకు వీలైతే, లేదు తప్పనిసరి కన్స్ట్రక్టర్.

దీనిని ప్రయత్నించండి

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

ఫ్యాక్టరీ ఫంక్షన్‌ని వ్రాయండి NewUser(పేరు స్ట్రింగ్, వయస్సు పూర్ణాంకం) * &యూజర్{పేరు: పేరు, వయస్సు: వయస్సు}ని తిరిగి ఇచ్చే వినియోగదారు.

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

పాయింటర్‌ను తిరిగి ఇవ్వడానికి అక్షరార్థ `&యూజర్{...}` ఉపయోగించండి.

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

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

న్యూయూజర్‌ని (పేరు స్ట్రింగ్)గా మార్చండి (*యూజర్, ఎర్రర్): పేరు == ''నిల్ రిటర్న్ చేస్తే, లోపాలు.కొత్త('నోమ్ ఆబ్లిగేటోరియో').

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

ముందస్తు షరతులు ఉంటే, రిటర్న్ (*T, ఎర్రర్) మరియు వైఫల్యంపై nil + ఎర్రర్ రిటర్న్ చేయండి.

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

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

గోలో కన్స్ట్రక్టర్‌ల కోసం ఇడియోమాటిక్ కన్వెన్షన్ ఏమిటి?

Go
// Which signature is more idiomatic?
సమాధాన ఎంపికలు

రీక్యాప్

  • కాదు constructor: NewT ఫంక్షన్‌ను ఉపయోగించండి (లేదా అదే పేరుతో ఉన్న ప్యాకేజీలో New).
  • సాధారణ కేసు కోసం *Tని తిరిగి ఇవ్వండి; (*T, error) ముందస్తు షరతులు లేదా ధ్రువీకరణతో.
  • ఎర్రర్‌లో: nilని పాయింటర్‌గా మరియు వివరణాత్మక లోపాన్ని రెండవ విలువగా అందించండి.
  • ఓవర్‌లోడింగ్ లేదు; వివరణాత్మక పేర్లను ఉపయోగించండి (NewUserFromJSON, NewAdmin).
  • "సున్నా విలువను ఉపయోగకరంగా చేయండి": మీకు వీలైతే, కన్స్ట్రక్టర్ అనవసరం.
  • అనేక ఐచ్ఛిక పారామితుల కోసం అధునాతన నమూనా: ఫంక్షనల్ ఎంపికలు.