Rust – RefCell(T) и внутренняя изменчивость

Опубликовано: 24 Февраля, 2023

.Rust — это безопасный для памяти скомпилированный язык программирования, который обеспечивает высокую простоту при низкой производительности. Это популярный выбор для создания систем, где производительность абсолютно критична, таких как базы данных игрового движка или операционные системы, и это отличный выбор для веб-сборки. Он начинался как побочный проект сетки на четырех в 2007 году.

Он был спонсирован Mozilla в 2009 году и ежегодно с 2016 года считается самым любимым языком программирования<T>.

Давайте рассмотрим тип RefCell<T>, который следует за внутренней маркировкой изменчивости. Где внутренняя изменчивость Rust — это маркировка карты, которая позволяет вам изменять данные, даже если ссылки на них не могут быть изменены; (В большинстве случаев правила заимствования не допускают такого поведения.)

RefCell<T>:

  • RefCell<T>, который сам по себе не является интеллектуальным указателем, но управляет доступом к «интеллектуальным указателям, таким как Ref и RefMut, для реализации правил заимствования во время выполнения, а не во время компиляции».
  • RefCell<T> представляет один заголовок с подсчетом ссылок.
  • RefCell<T> использует подсчет ссылок для отслеживания количества активных норок во время работы программы.
  • RefCell<T> в основном используется в схеме с уникальным потоком, но в многопоточной схеме он не будет точным.
  • Кроме того, подсчет ссылок в RefCell<T> не является потокобезопасным, поэтому невозможно совместно использовать данные RefCell<T> между потоками.

Важные моменты, которые следует помнить:

  1. Маркировка нарушает обычные правила мутации и заимствования, которым следует Rust, чтобы изменять данные, используя незашифрованный код в структуре данных.
  2. Классы с проявлением внутренней изменчивости все еще можно использовать, даже если компилятор не может гарантировать, что правила заимствования будут обнаружены во время выполнения.
  3. После этого задействованный незашифрованный код помещается в защищенный API, а самый внешний тип по-прежнему можно изменить.
  4. RefCell<T> полезен, когда вы знаете, что правила заимствования соблюдаются, но компилятор не может понять, что это правда.

Внутренняя изменчивость:

Шаблон изменчивости, в котором неизменяемый тип раскрывает API для изменения внутреннего значения и правил заимствования. Отметка «Внутренняя изменчивость» предполагает использование незащищенного кода в структуре данных для изменения обычных правил Rust посредством мутаций и заимствований. Когда компилятор не может гарантировать соблюдение правил заимствования во время выполнения, используется шаблон внутренней изменчивости. После этого небезопасный код покрывается безопасным API, а внешний тип остается неизменным.

У нас может быть список, неизменяемый снаружи, с помощью RefCell<T>, но мы можем использовать методы RefCell<T>, чтобы получить доступ к его внутренней изменчивости, чтобы мы могли изменять наши данные, когда нам нужно. Мы решили немного пожертвовать скоростью в обмен на большую гибкость наших структур данных, потому что RefCell<T> предотвращает гонки данных.

Давайте рассмотрим сценарий, в котором мы можем использовать RefCell<T> для изменения неизменяемого значения. Например, когда у вас есть значение, которое нельзя изменить, вы не можете заимствовать его каким-либо образом из-за правил заимствования.

Пример 1:

Выход :

Запрос завершился неудачно с кодом состояния 400. Мы видели, что неизменяемое значение не может быть заимствовано изменяемым образом в приведенном выше примере. Однако единственным методом достижения внутренней изменчивости является RefCell.

Пример 2:

Выход :

Помимо RefCell<T>, в стандартной библиотеке есть и другие типы, предлагающие внутреннюю изменчивость. (Cell<T> аналогичен, но вместо того, чтобы давать ссылки на внутреннее значение, как это делает RefCell<T>, значение копируется в Cell<T> и из него. Mutex<T> предлагает внутреннюю изменчивость, которую безопасно использовать во всех потоки.