মডিউল পাঠ (3/5)
রচনা (এম্বেডিং)
যান কোন উত্তরাধিকার আছে. পুনঃব্যবহারের ইডিওম্যাটিক উত্তর হল কম্পোজিশন, এবং বিশেষ করে এম্বেডিং: এক প্রকার সহ এটি একটি ক্ষেত্রের নাম না দিয়ে অন্য ভিতরে. এর ক্ষেত্র এবং পদ্ধতি এমবেডেড টাইপ প্রচারিত হয়, সরাসরি অ্যাক্সেসযোগ্য হয়ে উঠছে যেন তারা বাইরের ধরনের অন্তর্গত ছিল.
স্ট্রাকট এম্বেডিং
type Animal struct {
Name string
}
func (a Animal) Greet() string {
return "ciao da " + a.Name
}
type Dog struct {
Animal // embedding — NO field name
Breed string
}
c := Dog{
Animal: Animal{Name: "Rex"},
Breed: "Pastore",
}
fmt.Println(c.Name) // "Rex" — promoted from Animal
fmt.Println(c.Greet()) // "ciao da Rex" — promoted method
fmt.Println(c.Breed) // own fieldএমবেড করা ক্ষেত্রটি এখনও টাইপের নামের দ্বারা অ্যাক্সেসযোগ্য:
c.Animal.Name কাজ করে এবং c.Name এর সাথে অভিন্ন৷ এটা প্রয়োজন যখন
সংঘর্ষ আছে।
ওভাররাইড (আংশিক): পদ্ধতি "ছায়া করা"
যদি বাইরের ধরনটি প্রচারিত হিসাবে একই নামের একটি পদ্ধতি সংজ্ঞায়িত করে এক, এর পদ্ধতি "জয়"। ভিতরে থেকে আপনি সবসময় এমবেডেড পৌঁছাতে পারেন টাইপের নামের মাধ্যমে একটি:
func (c Dog) Greet() string {
return "BAU! " + c.Animal.Greet()
}এটি বহুরূপী উত্তরাধিকার নয়: এটি শুধুমাত্র আভিধানিক নামের রেজোলিউশন। পলিমারফিজমের জন্য আপনি ইন্টারফেস ব্যবহার করেন (মডিউল 6)।
একাধিক এম্বেডিং
আপনি একাধিক প্রকার এম্বেড করতে পারেন:
type Logger struct{ /*...*/ }
func (l Logger) Log(msg string) { /*...*/ }
type Timer struct{ /*...*/ }
func (t Timer) Now() time.Time { /*...*/ }
type Service struct {
Logger
Timer
Name string
}
s := Service{Name: "api"}
s.Log("start") // promoted from Logger
s.Now() // promoted from Timerযদি দুটি এমবেডেড প্রকারের একই নামের একটি পদ্ধতি থাকে, সরাসরি অ্যাক্সেস
অস্পষ্ট হয়ে ওঠে এবং কম্পাইলারের স্পষ্ট ফর্ম প্রয়োজন
(s.Logger.Foo() বা s.Timer.Foo())।
ইন্টারফেস এম্বেডিং
ইন্টারফেসগুলিও "এমবেডেড" হতে পারে (মডিউল 6 দেখুন):
type ReadWriter interface {
io.Reader
io.Writer
}এটি Reader এর এবং Writer এর পদ্ধতির মিলনের সমতুল্য।
কখন সুস্পষ্ট রচনা ব্যবহার করবেন (এমবেডিং নয়)
আপনি যদি একটি নামযুক্ত ক্ষেত্র চান এবং স্বয়ংক্রিয় প্রচার না চান, তাহলে প্লেইন ব্যবহার করুন রচনা:
type Dog struct {
Anim Animal // NORMAL field, no promotion
Breed string
}
c.Anim.Name // you need the field nameএম্বেডিং একটি সহজ ডেলিগেশন টুল, ডিজাইন পছন্দ নয় স্পষ্ট রচনার চেয়ে কঠোরভাবে ভাল: আপনি যখন সত্যিই চান তখন এটি ব্যবহার করুন অভ্যন্তরীণ প্রকারের API প্রচার করতে।
চেষ্টা করে দেখুন
কুকুরকে সংজ্ঞায়িত করুন যা প্রাণীকে এম্বেড করে (এম্বেড করা, কোনও ক্ষেত্রের নাম নেই) এবং একটি ব্রিড স্ট্রিং ক্ষেত্র রয়েছে।
ইঙ্গিত দেখান
এমবেডিং: একটি ক্ষেত্রের নাম না দিয়ে TYPE লিখুন।
সমাধান 3 প্রচেষ্টার পরে উপলব্ধ
পশুতে একটি Greet() স্ট্রিং পদ্ধতি যোগ করুন এবং এটিকে সরাসরি একটি কুকুর ভেরিয়েবলে কল করুন (পদ্ধতি প্রচার)।
ইঙ্গিত দেখান
প্রাণীর উপর সংজ্ঞায়িত পদ্ধতিটি এম্বেড করার জন্য কুকুরকে উন্নীত করা হয়।
সমাধান 3 প্রচেষ্টার পরে উপলব্ধ
Go কি শাস্ত্রীয় উত্তরাধিকার সমর্থন করে?
type B struct { /* extends A? */ }রিক্যাপ
- কোন উত্তরাধিকার নেই: আপনি এম্বেডিং দিয়ে রচনা করেন।
- এমবেডিং = স্ট্রাকটে একটি ক্ষেত্রের নাম ছাড়াই TYPE লেখা।
- এম্বেড করা টাইপের ক্ষেত্র এবং পদ্ধতি উন্নীত হয়।
- স্পষ্ট অ্যাক্সেস সর্বদা উপলব্ধ:
outer.Inner.Field। - "লেক্সিকাল" ওভাররাইড: বাইরের প্রকারের পদ্ধতিটি প্রচারিতটিকে ছায়া দেয়৷
- এম্বেডিং ≠ is-a: পলিমারফিজমের জন্য ইন্টারফেস ব্যবহার করুন।