ماڈیول اسباق (5/5)
'نیا...' کنسٹرکٹر پیٹرن
Go کے پاس کوئی constructor کلیدی لفظ نہیں ہے۔ کنونشن ایک ** فیکٹری ہے۔
فنکشن** جو مناسب طریقے سے ابتدائی قیمت یا پوائنٹر لوٹاتا ہے۔ کی طرف سے
اسے عام طور پر NewT (یا NewXxx) کہا جاتا ہے۔
بیس پیٹرن: نیو ٹی
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):
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...
}یہ کسی بھی کنسٹرکٹر کے لیے محاوراتی نمونہ ہے۔ پیشگی شرائط: ڈی بی کنکشن، فائل ہینڈل، سرور کی تشکیل، وغیرہ۔
متعدد تعمیر کنندگان
اگر آپ کے پاس تعمیر کرنے کے متعدد "طریقے" ہیں تو وضاحتی نام استعمال کریں:
func NewUser(name string) *User { ... }
func NewUserFromJSON(data []byte) (*User, error) { ... }
func NewAdmin() *User { ... }گو میں کوئی اوورلوڈنگ نہیں: نام کو واضح کرتا ہے۔
فنکشنل اختیارات (جدید جھلک)
جب بہت سے اختیاری پیرامیٹرز ہیں، محاورہ پیٹرن ہے "فعال اختیارات":
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 پہلے سے ہی استعمال کے لیے تیار ایک mutex ہے۔ bytes.Buffer کے لیے بھی ایسا ہی۔
اصول یہ ہے: "صفر کی قدر کو کارآمد بنائیں"۔ اگر آپ کر سکتے ہیں، نہیں لازمی تعمیر کنندہ.
اسے آزمائیں
فیکٹری فنکشن لکھیں NewUser(name string, age int) *User جو واپس کرتا ہے &User{Name: name, Age: age}۔
اشارہ دکھائیں۔
پوائنٹر واپس کرنے کے لیے لفظی `&User{...}` کا استعمال کریں۔
3 کوششوں کے بعد حل دستیاب ہے۔
نیو یوزر کو (نام کی تار) میں تبدیل کریں (*صارف، غلطی): اگر نام == '' واپس نہ آئے تو غلطیاں۔ نیا('نوم واجب الادا')۔
اشارہ دکھائیں۔
اگر پیشگی شرائط ہیں تو واپسی (*T، غلطی) اور ناکامی پر nil + error واپس کریں۔
3 کوششوں کے بعد حل دستیاب ہے۔
گو میں کنسٹرکٹرز کے لیے محاورہ کنونشن کیا ہے؟
// Which signature is more idiomatic?Recap
- نہیں
constructor: ایکNewTفنکشن استعمال کریں (یا اسی نام والے پیکیج کے اندرNew)۔ - سادہ کیس کے لیے
*Tواپس کریں؛(*T, error)پیشگی شرائط یا توثیق کے ساتھ۔ - غلطی پر: پوائنٹر کے طور پر
nilاور دوسری قدر کے طور پر وضاحتی غلطی واپس کریں۔ - کوئی اوورلوڈنگ نہیں؛ وضاحتی نام استعمال کریں (
NewUserFromJSON,NewAdmin)۔ - "صفر قدر کو کارآمد بنائیں": اگر آپ کر سکتے ہیں تو، کنسٹرکٹر غیر ضروری ہے۔
- بہت سے اختیاری پیرامیٹرز کے لیے ایڈوانسڈ پیٹرن: فنکشنل آپشنز۔