Внедряване на AnyMap и време за изпълнение на `struct Port(u32);`

Четох „24 days of Rust“ и примера за AnyMap използване току-що взриви ума ми. Разгледайте следния код:

#[deriving(Show)]
struct Port(u32);

#[deriving(Show)]
struct ConnectionLimit(u32);

Казва:

Тук типовете Port и ConnectionLimit са абстракции над основното цяло число (без допълнителни разходи по време на изпълнение!).

Много добре, разбирам как може да се постигне това. Всички типове се проверяват по време на компилация и по време на изпълнение имаме само u32. Но в този случай как е възможно да се създаде карта от някакво TypeId до Box<Any>? И как Any може да бъде кастинг към всеки подтип, като u32?

изходният код на AnyMap е доста сложен и включва много метапрограмиране. Как работи? Може би просто има грешка в „24 days of Rust“ и Port и ConnectionLimit всъщност имат време за изпълнение?


person Aleksander Alekseev    schedule 14.04.2015    source източник


Отговори (1)


Всъщност е доста обичайно в C, C++ и други системни езици да има различни типове с едно и също представяне в паметта.

В памет:

  • a u32 е 4 последователни байта памет
  • a Port е 4 последователни байта памет
  • a ConnectionLimit е 4 последователни байта памет

Трябва да се отбележи, че в сравнение с много други езици, няма "виртуална таблица" или друга външна информация, съхранявана в паметта за всеки екземпляр от тези типове.

Що се отнася до AnyMap, в точката, в която съхранявате вашия обект в картата, компилаторът знае типа на обекта и следователно може да предостави правилното TypeId. След това това трябва да се носи заедно с данните за обекта, защото ако някога се загуби, не може да бъде възстановено.

person Matthieu M.    schedule 14.04.2015
comment
И така, TypeId е просто константа, генерирана по време на компилацията и използвана в общи функции за получаване/задаване. И според изходния код, типовете се прехвърлят към/от Any in unsafe block, което всъщност е доста безопасно, защото знаем точно кой тип се използва във всяка обща функция. нали - person Aleksander Alekseev; 14.04.2015
comment
@afiskon: Можете да използвате Any без unsafe, доколкото знам, но самият той е имплементиран с unsafe зад кулисите, защото манипулира необработената памет. - person Matthieu M.; 14.04.2015
comment
Само за да бъде ясно, функционалността на anymap може да бъде внедрена в напълно безопасен код; просто може да бъде направено малко по-ефективно чрез използването на опасен код там, който наистина е безпогрешен, тъй като TypeId също се съхранява като ключ и е известен статично чрез общи ограничения и т.н. - person Chris Morgan; 14.04.2015