মডিউল পাঠ (5/5)
'নতুন...' কনস্ট্রাক্টর প্যাটার্ন
Go এর কোনো constructor কীওয়ার্ড নেই। সম্মেলন একটি কারখানা
ফাংশন যেটি সঠিকভাবে প্রারম্ভিক মান বা পয়েন্টার প্রদান করে। দ্বারা
নাম এটিকে সাধারণত NewT (বা NewXxx) বলা হয়।
বেস প্যাটার্ন: NewT
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 ইতিমধ্যেই একটি ব্যবহারের জন্য প্রস্তুত মিউটেক্স৷ bytes.Buffer এর জন্য একই।
নিয়মটি হল: "শূন্য মানকে দরকারী করুন"। আপনি যদি পারেন, না বাধ্যতামূলক নির্মাণকারী।
চেষ্টা করে দেখুন
ফ্যাক্টরি ফাংশন লিখুন NewUser(name string, age int) *ব্যবহারকারী যেটি &User{Name: name, Age: age} প্রদান করে।
ইঙ্গিত দেখান
একটি পয়েন্টার ফেরত দিতে আক্ষরিক `&User{...}` ব্যবহার করুন।
সমাধান 3 প্রচেষ্টার পরে উপলব্ধ
নিউইউসারকে (নাম স্ট্রিং) এ পরিণত করুন (*ব্যবহারকারী, ত্রুটি): যদি নাম == '' রিটার্ন শূন্য, errors.New('nome obbligatorio')।
ইঙ্গিত দেখান
যদি পূর্বশর্ত থাকে, তবে ফেরত দিন (*T, ত্রুটি) এবং ব্যর্থ হলে nil + ত্রুটি ফেরত দিন।
সমাধান 3 প্রচেষ্টার পরে উপলব্ধ
গো-তে কনস্ট্রাক্টরদের জন্য ইডিওম্যাটিক কনভেনশন কী?
// Which signature is more idiomatic?রিক্যাপ
- না
constructor: একটিNewTফাংশন ব্যবহার করুন (অথবাNewএকই নামের প্যাকেজের ভিতরে)। - সাধারণ ক্ষেত্রের জন্য
*Tরিটার্ন করুন;(*T, error)পূর্বশর্ত বা বৈধতা সহ। - ত্রুটিতে: পয়েন্টার হিসাবে
nilএবং দ্বিতীয় মান হিসাবে ব্যাখ্যামূলক ত্রুটি ফেরত দিন। - কোন ওভারলোডিং; বর্ণনামূলক নাম ব্যবহার করুন (
NewUserFromJSON,NewAdmin)। - "শূন্য মানকে উপযোগী করুন": আপনি যদি পারেন, কনস্ট্রাক্টরটি অপ্রয়োজনীয়।
- অনেক ঐচ্ছিক প্যারামিটারের জন্য উন্নত প্যাটার্ন: কার্যকর বিকল্প।