Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Умные указатели

Указатель – это общее понятие для переменной, которая содержит адрес в памяти. Этот адрес ссылается, или “указывает”, на какие-то другие данные. Самый распространенный вид указателя в Rust – это ссылка, о которой вы узнали в главе 4. Ссылки обозначаются символом & и заимствуют значение, на которое указывают. У них нет никаких особых возможностей, кроме ссылки на данные, и они не имеют накладных расходов.

Умные указатели, с другой стороны, – это структуры данных, которые ведут себя как указатель, но также имеют дополнительные метаданные и возможности. Концепция умных указателей не уникальна для Rust: умные указатели появились в C++ и существуют также в других языках. В стандартной библиотеке Rust определено несколько умных указателей, которые предоставляют функциональность сверх той, что дают ссылки. Чтобы изучить общую концепцию, мы рассмотрим несколько разных примеров умных указателей, включая тип умного указателя с подсчетом ссылок. Такой указатель позволяет данным иметь нескольких владельцев, отслеживая количество владельцев и очищая данные, когда владельцев больше не остается.

В Rust, с его концепцией владения и заимствования, есть еще одно различие между ссылками и умными указателями: ссылки только заимствуют данные, тогда как во многих случаях умные указатели владеют данными, на которые указывают.

Умные указатели обычно реализуются с помощью структур. В отличие от обычной структуры, умные указатели реализуют трейты Deref и Drop. Трейт Deref позволяет экземпляру структуры умного указателя вести себя как ссылка, чтобы вы могли писать код, работающий и со ссылками, и с умными указателями. Трейт Drop позволяет настраивать код, который выполняется, когда экземпляр умного указателя выходит из области видимости. В этой главе мы обсудим оба этих трейта и покажем, почему они важны для умных указателей.

Поскольку шаблон умного указателя – это общий шаблон проектирования, часто используемый в Rust, эта глава не будет охватывать все существующие умные указатели. У многих библиотек есть собственные умные указатели, и вы даже можете написать свой. Мы рассмотрим самые распространенные умные указатели в стандартной библиотеке:

  • Box<T> для выделения значений в куче
  • Rc<T>, тип с подсчетом ссылок, который делает возможным множественное владение
  • Ref<T> и RefMut<T>, доступные через RefCell<T>, тип, который обеспечивает правила заимствования во время выполнения, а не во время компиляции

Кроме того, мы рассмотрим шаблон внутренней изменяемости, при котором неизменяемый тип предоставляет API для изменения внутреннего значения. Мы также обсудим циклы ссылок: как они могут приводить к утечкам памяти и как их предотвращать.

Приступим!