При чтении типа &'a mut T что именно ограничено временем жизни 'a?
В типе &'a mut T 'a обозначает срок действия изменяемого заимствования, то есть период, в течение которого ссылка может использоваться эксклюзивно. Он не задаёт срок жизни самого значения T и не продлевает его.
После окончания 'a значение T может продолжить существовать, если у вызывающего кода сохранилось владение им и нет других ограничений заимствования.
Времена жизни нужны Rust для статической проверки ссылок без сборщика мусора. Компилятор должен доказать, что ссылка не используется после уничтожения объекта и что изменяемый доступ не пересекается с несовместимыми обращениями.
Разделение срока жизни ссылки и срока жизни объекта позволяет безопасно временно передавать объект функциям, не превращая это заимствование в передачу владения.
Изменяемая ссылка одновременно даёт доступ к объекту и запрещает конкурирующие обращения к нему на время заимствования. Если ошибочно считать, что 'a описывает жизнь T, можно неверно ожидать, что объект будет уничтожен после завершения ссылки или, наоборот, что ссылка автоматически сохранится до конца жизни объекта.
Компилятор должен контролировать именно период эксклюзивного доступа. Сам объект может жить дольше, чем этот период, но не может быть использован через исходное владение, пока активна соответствующая изменяемая ссылка.
В &'a mut T тип T описывает, к какому значению обращаются, а 'a — сколько действует заимствование этого значения. В течение 'a ссылка считается единственным разрешённым способом доступа к объекту: нельзя одновременно читать объект через исходное имя или создавать другое пересекающееся заимствование.
В примере text живёт до конца main, а изменяемое заимствование действует только внутри вложенного блока. После его завершения исходное владение снова доступно, поэтому text.push('?') допустим.
Аннотация 'a не является командой «держать ссылку ровно столько». Это параметр связи между типами и операциями: фактический срок заимствования может оказаться короче указанной области, если этого достаточно для использования. Современный анализ времени жизни также может завершить заимствование в последней точке его использования, а не только в конце внешнего блока.
При этом T может сам содержать ссылки. Тогда их собственные времена жизни должны быть совместимы с использованием T; аннотация внешней ссылки не делает вложенные ссылки бессрочными и не продлевает их.
Главный компромисс таков: более долгий срок изменяемого заимствования обеспечивает возможность вернуть или сохранить ссылку, но дольше блокирует исходный доступ к объекту. Если API не должен удерживать эксклюзивный доступ, лучше ограничить заимствование более узким участком или вернуть принадлежащее значение вместо ссылки.
Представим парсер, который получает изменяемый буфер и возвращает представление найденного фрагмента. Вариант с результатом, связанным с 'a, удобен: результат не копирует данные и не может пережить заимствование буфера. Однако пока такой результат используется, буфер нельзя изменять, потому что представление должно оставаться корректным.
Можно выбрать один из подходов:
Если фрагмент нужен только для немедленной проверки, обычно выбирают ссылку с коротким заимствованием. Если результат должен сохраняться независимо от дальнейших изменений буфера, обоснованнее вернуть принадлежащие данные или позиционный дескриптор с явно определёнными гарантиями.
T быть уничтожено до окончания 'a?Нет, безопасная программа не может уничтожить или переместить значение так, чтобы действующая ссылка стала недействительной. Время жизни ссылки не продлевает T; оно ограничивает допустимое использование так, чтобы T оставалось доступным весь период заимствования.
'a объект снова можно изменять через исходную переменную?Потому что завершилось эксклюзивное заимствование, а не жизнь объекта. Владение объектом всё это время оставалось у исходной переменной; компилятор лишь временно запрещал обращаться к ней напрямую, пока &mut T имел право доступа.
T содержит собственную ссылку?Появляется дополнительное ограничение: объект T нельзя безопасно использовать дольше, чем живут ссылки внутри него. Внешнее 'a описывает заимствование самого объекта, но не заменяет и не увеличивает времена жизни вложенных ссылок; все эти ограничения должны одновременно выполняться.