মূল কন্টেন্টে যান
মডিউল 5 · 3-এর পাঠ 5কোর্সে 23/50~12 min
মডিউল পাঠ (3/5)

রচনা (এম্বেডিং)

যান কোন উত্তরাধিকার আছে. পুনঃব্যবহারের ইডিওম্যাটিক উত্তর হল কম্পোজিশন, এবং বিশেষ করে এম্বেডিং: এক প্রকার সহ এটি একটি ক্ষেত্রের নাম না দিয়ে অন্য ভিতরে. এর ক্ষেত্র এবং পদ্ধতি এমবেডেড টাইপ প্রচারিত হয়, সরাসরি অ্যাক্সেসযোগ্য হয়ে উঠছে যেন তারা বাইরের ধরনের অন্তর্গত ছিল.

স্ট্রাকট এম্বেডিং

Go
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 এর সাথে অভিন্ন৷ এটা প্রয়োজন যখন সংঘর্ষ আছে।

ওভাররাইড (আংশিক): পদ্ধতি "ছায়া করা"

যদি বাইরের ধরনটি প্রচারিত হিসাবে একই নামের একটি পদ্ধতি সংজ্ঞায়িত করে এক, এর পদ্ধতি "জয়"। ভিতরে থেকে আপনি সবসময় এমবেডেড পৌঁছাতে পারেন টাইপের নামের মাধ্যমে একটি:

Go
func (c Dog) Greet() string {
    return "BAU! " + c.Animal.Greet()
}

এটি বহুরূপী উত্তরাধিকার নয়: এটি শুধুমাত্র আভিধানিক নামের রেজোলিউশন। পলিমারফিজমের জন্য আপনি ইন্টারফেস ব্যবহার করেন (মডিউল 6)।

একাধিক এম্বেডিং

আপনি একাধিক প্রকার এম্বেড করতে পারেন:

Go
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 দেখুন):

Go
type ReadWriter interface {
    io.Reader
    io.Writer
}

এটি Reader এর এবং Writer এর পদ্ধতির মিলনের সমতুল্য।

কখন সুস্পষ্ট রচনা ব্যবহার করবেন (এমবেডিং নয়)

আপনি যদি একটি নামযুক্ত ক্ষেত্র চান এবং স্বয়ংক্রিয় প্রচার না চান, তাহলে প্লেইন ব্যবহার করুন রচনা:

Go
type Dog struct {
    Anim  Animal    // NORMAL field, no promotion
    Breed string
}
c.Anim.Name   // you need the field name

এম্বেডিং একটি সহজ ডেলিগেশন টুল, ডিজাইন পছন্দ নয় স্পষ্ট রচনার চেয়ে কঠোরভাবে ভাল: আপনি যখন সত্যিই চান তখন এটি ব্যবহার করুন অভ্যন্তরীণ প্রকারের API প্রচার করতে।

চেষ্টা করে দেখুন

ব্যায়াম#go.m5.l3.e1
প্রচেষ্টা: 0লোড হচ্ছে...

কুকুরকে সংজ্ঞায়িত করুন যা প্রাণীকে এম্বেড করে (এম্বেড করা, কোনও ক্ষেত্রের নাম নেই) এবং একটি ব্রিড স্ট্রিং ক্ষেত্র রয়েছে।

সম্পাদক লোড হচ্ছে...
ইঙ্গিত দেখান

এমবেডিং: একটি ক্ষেত্রের নাম না দিয়ে TYPE লিখুন।

সমাধান 3 প্রচেষ্টার পরে উপলব্ধ

ব্যায়াম#go.m5.l3.e2
প্রচেষ্টা: 0লোড হচ্ছে...

পশুতে একটি Greet() স্ট্রিং পদ্ধতি যোগ করুন এবং এটিকে সরাসরি একটি কুকুর ভেরিয়েবলে কল করুন (পদ্ধতি প্রচার)।

সম্পাদক লোড হচ্ছে...
ইঙ্গিত দেখান

প্রাণীর উপর সংজ্ঞায়িত পদ্ধতিটি এম্বেড করার জন্য কুকুরকে উন্নীত করা হয়।

সমাধান 3 প্রচেষ্টার পরে উপলব্ধ

Quiz#go.m5.l3.e3
প্রস্তুত

Go কি শাস্ত্রীয় উত্তরাধিকার সমর্থন করে?

Go
type B struct { /* extends A? */ }
উত্তরের বিকল্প

রিক্যাপ

  • কোন উত্তরাধিকার নেই: আপনি এম্বেডিং দিয়ে রচনা করেন।
  • এমবেডিং = স্ট্রাকটে একটি ক্ষেত্রের নাম ছাড়াই TYPE লেখা।
  • এম্বেড করা টাইপের ক্ষেত্র এবং পদ্ধতি উন্নীত হয়।
  • স্পষ্ট অ্যাক্সেস সর্বদা উপলব্ধ: outer.Inner.Field।
  • "লেক্সিকাল" ওভাররাইড: বাইরের প্রকারের পদ্ধতিটি প্রচারিতটিকে ছায়া দেয়৷
  • এম্বেডিং ≠ is-a: পলিমারফিজমের জন্য ইন্টারফেস ব্যবহার করুন।