Подтвердить что ты не робот

Требуется целостный пояснения о ячейках Rust и ссылочных подсчитанных типах

Я потерялся с типами в std::cell module. Я также пытаюсь понять обертки с подсчетом ссылок в Rust, например Rc и Arc.

Как я понимаю, это обертки, которые предоставляют дополнительные возможности, чем простая ссылка. Хотя я понимаю основы (RefCell дает "динамическое заимствование" и Rc действует как shared_ptr в С++), я все еще не вижу всей картины.

Каковы ссылки с Rc и Arc? Являются ли ячейки и ссылочные подсчитанные семейства ортогональными функциями?

4b9b3361

Ответ 1

В Rust есть две основные понятия:

  • собственности
  • Изменчивость.

Различные типы указателей (Box, Rc, Arc) связаны с собственностью: они позволяют контролировать, существует ли один или несколько владельцев для одного объекта.

С другой стороны, различные ячейки (Cell, RefCell, Mutex, RwLock, AtomicXXX) связаны с Mutability.


Основополагающее правило безопасности Rust Сглаживание XOR Mutability. То есть, объект может быть безопасно мутирован, если нет заметной ссылки на его интерьер.

Это правило обычно применяется во время компиляции с помощью средства проверки заемщика:

  • если у вас есть &T, вы также не можете иметь &mut T для одного и того же объекта в области видимости,
  • если у вас есть &mut T, вы также не можете ссылаться на один и тот же объект в области видимости.

Однако иногда это недостаточно гибко. Иногда вам нужно (или нужно) возможность иметь несколько ссылок на один и тот же объект и все же мутировать его. Введите ячейки.

Идея Cell и RefCell заключается в том, чтобы разрешить изменчивость при наличии сглаживания контролируемым образом:

  • Cell предотвращает формирование ссылки на его внутренность, избегая оборванных ссылок,
  • RefCell сдвигает принудительное выполнение слияния XOR Mutability от времени компиляции до времени выполнения.

Эта функция иногда описывается как предоставление внутренней изменчивости, то есть объект, который в противном случае выглядит неизменным снаружи (&T), может быть фактически мутирован.

Когда эта изменчивость распространяется на несколько потоков, вместо этого вы будете использовать Mutex, RwLock или AtomicXXX; они обеспечивают ту же функциональность:

  • AtomicXXX - это просто Cell: нет ссылки на интерьер, просто перемещаясь/выходите,
  • RwLock - это просто RefCell: можно получить ссылки на интерьер через охранники,
  • Mutex - упрощенный вариант RwLock, который не проводит различия между защитой только для чтения и защитой записи; поэтому концептуально похож на a RefCell с помощью только метода borrow_mut.

Если вы пришли из фона С++:

  • Box unique_ptr,
  • Arc - shared_ptr,
  • Rc является небезопасной версией shared_ptr.

И ячейки предоставляют аналогичную функциональность, как mutable, за исключением дополнительных гарантий, чтобы избежать проблем с псевдонимом; подумайте Cell как std::atomic и RefCell как небезопасную версию std::shared_mutex (которая вместо блокировки блокируется, если блокировка выполнена).