Mutex
не имеет так называемого структурного закрепления , которое описано в документации к модулю std::pin
:
Получается что сам автор структуры данных должен решить, превратится ли закрепленная проекция для определенного поля в Pin<&mut Struct>
в Pin<&mut Field>
или &mut Field
. [...] Как автор структуры данных, вы решаете для каждого поля, будет ли пиннинг «распространяться» на это поле или нет. Пиннинг, который распространяется, также называется "структурным", потому что он следует структуре типа .
Mutex<T>
не имеет структурного пиннинга, потому что пиннинг структуры (Mutex
) не распространяется на поле (T
) - это является безопасным для получения открепленного &mut T
от Pin<&mut Mutex<T>>
(то есть, используя вместо этого Deref
DerefMut
и блокировки мьютекса), даже если T
и Mutex<T>
равны !Unpin
.
Чтобы превратить это &mut T
в Pin<&mut T>
, вы должны сделать еще один уровень непроверенной гарантии, используя unsafe
и Pin::new_unchecked
, чтобы доказать, что сам T
никогда не перемещается. Кажется, это противоречит цели «внешнего» * 1039 *.
В зависимости от того, что позволяют ваши структуры данных, вы можете рассмотреть один из следующих вариантов:
- написание оболочки для
Arc<Mutex>
, который прикрепляет содержимое Mutex
при доступе через Pin
(вы не могли реализовать Deref
, но вы могли бы написать методы, которые возвращали MutexGuard
s и выполняли внутреннее обертывание Pin
) - просто отправляет разделяемую изменяемость в тип, который реализует
Stream
, если ваша структура данных позволяет это.