Розумні вказівники (smart pointers)
Вказівник — це загальне поняття для змінної, яка містить адресу в
пам’яті. Ця адреса посилається на деякі інші дані, або «вказує на» них. Найбільш
поширеним видом вказівника в Rust є посилання, про яке ви дізналися в
Розділі 4. Посилання позначаються символом & і запозичують значення, на яке вони
вказують. Вони не мають жодних особливих можливостей, окрім посилання на
дані, і не мають накладних витрат.
Розумні вказівники (smart pointers), з іншого боку, — це структури даних, які поводяться як вказівник, але також мають додаткові метадані та можливості. Концепція розумних вказівників не є унікальною для Rust: розумні вказівники походять із C++ і існують також в інших мовах. Rust має різноманітні розумні вказівники, визначені в стандартній бібліотеці, які надають функціональність понад ту, що надається посиланнями. Щоб дослідити загальне поняття, ми розглянемо кілька різних прикладів розумних вказівників, зокрема тип розумного вказівника з підрахунком посилань (reference counting). Цей вказівник дає змогу дозволити даним мати кількох власників, відстежуючи кількість власників і, коли не залишається жодного власника, очищаючи дані.
У Rust, з його поняттями власності та запозичення, існує додаткова різниця між посиланнями та розумними вказівниками: тоді як посилання лише запозичують дані, у багатьох випадках розумні вказівники володіють даними, на які вони вказують.
Розумні вказівники зазвичай реалізуються за допомогою структур. На відміну від звичайної
структури, розумні вказівники реалізують трейти Deref і Drop. Трейт Deref
дає змогу екземпляру структури розумного вказівника поводитися як посилання,
щоб ви могли писати свій код так, щоб він працював або з посиланнями, або з розумними
вказівниками. Трейт Drop дає змогу вам налаштовувати код, який запускається, коли
екземпляр розумного вказівника виходить з області видимості. У цьому розділі ми обговоримо
обидва ці трейти та продемонструємо, чому вони важливі для розумних вказівників.
З огляду на те, що шаблон розумного вказівника є загальним шаблоном проєктування, який часто використовується в Rust, цей розділ не охопить кожен наявний розумний вказівник. Багато бібліотек мають власні розумні вказівники, і ви навіть можете написати свій. Ми розглянемо найпоширеніші розумні вказівники у стандартній бібліотеці:
Box<T>, для розміщення значень у купіRc<T>, тип із підрахунком посилань, який дає змогу мати множинну власністьRef<T>іRefMut<T>, доступ до яких здійснюється черезRefCell<T>, тип, що забезпечує правила запозичення під час виконання, а не під час компіляції
Крім того, ми розглянемо шаблон внутрішньої змінності (interior mutability), де незмінний тип надає API для змінювання внутрішнього значення. Ми також обговоримо цикли посилань: як вони можуть призводити до витоку пам’яті та як цьому запобігти.
Тож занурмося в це!