Owned Trait Objects

پیش‌تر دیدیم که چگونه می‌توان ازویژگی اشیاء (trait objects) با ارجاعات استفاده کرد، مثلاً dyn Pet&. با این حال، می‌توانیم از اشیاء ویژگی با اشاره‌گرهای هوشمند مانند Box نیز استفاده کنیم تا یک شیء ویژگی مالک (owned trait object) ایجاد کنیم: <Box<dyn Pet.

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

چیدمان حافظه پس از تخصیص pets:

<Dog as Pet>::talk<Cat as Pet>::talkStackHeapFidoptrlives9len2capacity2data:name,4,4age5vtablevtablepets: Vec<dyn Pet>data: CatDogProgram text

Speaker Notes

This slide should take about 10 minutes.
  • تایپ‌هایی که ویژگی معین را پیاده‌سازی می‌کنند ممکن است اندازه‌های مختلفی داشته باشند. این موضوع باعث می‌شود که داشتن مواردی مانند <Vec<dyn Pet در مثال بالا غیرممکن باشد.
  • dyn Pet راهی است برای اطلاع دادن به کامپایلر درباره یک تایپ با اندازه پویا که ویژگی Pet را پیاده‌سازی می‌کند.
  • در این مثال، pets در stack تخصیص داده می‌شود و داده‌های vector در heap هستند. دو عنصر vector اشاره‌گرهای چاق (fat pointers) هستند:
    • اشاره‌گر چاق (fat pointer) یک اشاره‌گر با عرض دو برابر است. این اشاره‌گر دو مؤلفه دارد: یک اشاره‌گر به شیء واقعی و یک اشاره‌گر به روش‌های جدول مجازی (vtable) برای پیاده‌سازی Pet آن شیء خاص.
    • داده‌های مربوط به Dog به نام Fido شامل فیلدهای name و age است. Cat دارای فیلد lives است.
  • خروجی‌های زیر را در مثال بالا مقایسه کنید:
    println!("{} {}", std::mem::size_of::<Dog>(), std::mem::size_of::<Cat>()); println!("{} {}", std::mem::size_of::<&Dog>(), std::mem::size_of::<&Cat>()); println!("{}", std::mem::size_of::<&dyn Pet>()); println!("{}", std::mem::size_of::<Box<dyn Pet>>());