Что позволяет сделать Option::as_ref, не перемещая значение из Option?
Option::as_ref создаёт заимствованное представление Option<&T> из &Option<T>. Это позволяет проверить или преобразовать содержимое без перемещения объекта, поэтому исходный Option<T> остаётся доступен для дальнейшего использования.
В Rust владение значениями нельзя передавать неявно: операции, принимающие Option<T> по значению, обычно потребляют сам контейнер. Для строк, коллекций и других некопируемых типов это могло бы преждевременно лишить владельца доступа к данным.
Методы вроде as_ref выражают распространённую потребность в явном заимствовании: временно работать с содержимым контейнера, сохраняя его владение у исходной переменной.
Пусть Option<String> нужно проверить, получить длину строки или прочитать её поля, а затем передать исходную строку в другую функцию. Вызов операции, которая потребляет Option<String>, переместит значение и запретит дальнейшее использование переменной.
Копирование или клонирование решает проблему ценой дополнительной памяти и времени. Неправильное использование ссылок может привести к ошибке заимствования, если попытаться одновременно сохранить ссылку и изменить или переместить исходное значение.
as_ref принимает ссылку на Option<T> и возвращает Option<&T>: вариант Some(value) превращается в Some(&value), а None остаётся None. Само значение T не копируется и не перемещается; ссылка живёт не дольше исходного заимствования.
В length вызов as_ref преобразует &Option<String> в Option<&String>. Затем map получает ссылку на строку и возвращает её длину, а исходная переменная text после вызова остаётся владельцем String.
Это отличается от вызова map непосредственно на Option<String>: такой map принимает контейнер по значению и потребляет его. as_ref удобен именно тогда, когда нужно выполнить операцию чтения, но сохранить возможность позже переместить или изменить исходный Option.
В обработчике запроса есть необязательное поле конфигурации Option<String>. Сначала нужно проверить его длину для валидации, а после успешной проверки передать строку в объект, который станет её новым владельцем.
Можно клонировать строку, но это создаёт лишнюю копию и усложняет контроль затрат. Можно вручную сопоставить Option по ссылке, что корректно, но многословно. Вызов as_ref даёт компактное заимствованное представление для проверки, после чего исходный Option можно отдельно переместить; это обычно лучший компромисс между ясностью и отсутствием лишнего копирования.
Важно учитывать время жизни ссылки: пока заимствованное Option<&String> используется, нельзя конфликтующим образом перемещать или изменять исходную строку. Это ограничение предотвращает обращение к недействительной памяти.
Клонирует ли as_ref внутреннее значение?
Нет. Метод создаёт только ссылку на значение и новый лёгкий контейнер Option<&T>. Для Some(String) строковые данные не копируются; копируется лишь сама ссылка как значение указателя. Если требуется независимое владение строкой, as_ref его не создаёт — для этого явно нужен clone или другой способ получения нового значения.
Как получить изменяемую ссылку на содержимое Option?
Для этого используется as_mut, который при наличии изменяемого заимствования возвращает Option<&mut T>. Он позволяет изменить внутреннее значение без перемещения контейнера, но на время изменяемого заимствования исключает другие конфликтующие доступы к исходному Option.
Чем as_ref отличается от as_deref?
as_ref сохраняет непосредственный тип ссылки: из Option<String> получается Option<&String>. as_deref дополнительно применяет разыменование через trait Deref, поэтому для Option<String> результатом становится Option<&str>. as_deref удобен, когда вызываемая функция ожидает срез строки или другой целевой тип разыменования, но он так же не передаёт владение содержимым.