При автоматическом выводе времени жизни в методе с получателем-ссылкой какое входное время жизни связывается с возвращаемой ссылкой, если у метода есть другие ссылочные параметры?
Если метод имеет получатель &self или &mut self, правило элизии времён жизни связывает неаннотированное время жизни возвращаемой ссылки со временем жизни заимствования получателя. Это правило имеет приоритет над наличием других ссылочных параметров: результат считается действительным не дольше текущего заимствования self.
Явные времена жизни нужны Rust для проверки связей между заимствованиями, но повторение одинаковых параметров в простых сигнатурах сделало бы код избыточным. Поэтому в языке введены правила lifetime elision: компилятор добавляет пропущенные аннотации только там, где результат однозначен.
Эти правила не являются общим выводом типов и не анализируют тело функции для угадывания нужной связи. Они представляют собой небольшой фиксированный набор синтаксических правил, сохраняющий предсказуемость сигнатур.
У метода могут быть одновременно ссылка на self и другие ссылочные параметры. Если возвращаемая ссылка записана без явной аннотации, нужно определить, с каким входным заимствованием она связана.
Неверное предположение, будто результат автоматически получает самое длинное доступное время жизни или время жизни поля структуры, может привести к ошибочному пониманию безопасности. Фактический результат нельзя использовать после окончания заимствования получателя, даже если внутри него хранится ссылка с более длинным временем жизни.
Для методов действует специальное правило: если среди входных параметров есть ссылочный получатель self, то пропущенное время жизни результата связывается с временем жизни этого получателя. Другие ссылочные параметры не меняют это правило.
Например:
Сигнатура метода по смыслу эквивалентна варианту, где результат связан с конкретным заимствованием self, а не непосредственно с временем жизни Holder<'a>. Время жизни fallback при этом не связывается с результатом.
Следовательно, элизия не утверждает, что результат живёт столько же, сколько поле value. Поле может ссылаться на данные, существующие дольше, но доступ к нему через self ограничен сроком текущего заимствования самого объекта.
Если метод должен возвращать либо данные из self, либо fallback, одной элизии обычно недостаточно: необходимо явно выразить связь времён жизни и обеспечить, чтобы обе ссылки были совместимы с одним временем жизни результата. Если такой связи нет, безопаснее вернуть принадлежащее значение, например String, ценой дополнительного выделения или копирования.
Элизия также не продлевает ни одно заимствование. Она лишь сокращает запись уже существующей сигнатуры; после подстановки явных времён жизни правила проверки заимствований остаются теми же.
В API конфигурации метод возвращает значение из объекта настроек, а второй параметр содержит запасное значение. Разработчик может ожидать, что возвращаемая ссылка будет связана с запасным параметром, если значение из объекта отсутствует.
Вариант с неявной элизиёй удобен, когда метод всегда возвращает данные из self: сигнатура короткая, а срок результата корректно ограничен заимствованием объекта. Однако при добавлении ветки, возвращающей fallback, компилятор не должен молча выбрать более длинное время жизни.
Вариант с явными аннотациями точнее документирует связь, но может потребовать дополнительных ограничений на входные ссылки. Возврат String или другого владеющего типа устраняет зависимость результата от входных заимствований, но требует владения данными и может стоить дороже.
Практический выбор таков: для метода, возвращающего только данные объекта, оставить элизию; для объединения данных из нескольких источников явно описать связь времён жизни; если результат должен жить независимо от источников, вернуть владеющее значение.
Нет. Оно связывает результат с временной областью конкретного заимствования self. Параметр структуры Holder<'a> описывает, сколько может существовать ссылка внутри объекта, но не гарантирует, что сам объект или его заимствование будут доступны весь этот срок.
Даже если 'a длиннее текущего заимствования self, результат метода нельзя использовать после окончания этого заимствования, потому что результат логически получен через заимствованный объект.
self, но есть две входные ссылки?Автоматический вывод не сможет выбрать время жизни результата, если обе входные ссылки могут быть источниками возвращаемой ссылки. В такой сигнатуре требуется явная аннотация, связывающая результат с конкретным параметром или выражающая необходимое отношение между временами жизни.
Наличие метода само по себе не создаёт специального правила: решающим является именно ссылочный получатель self или &mut self.
Нет. Она только указывает типовую связь результата с заимствованием получателя. Фактическую длительность заимствования выбирает компилятор по местам использования результата; обычно она может быть короче всей области видимости.
Если результат хранится дольше и из-за этого конфликтует с последующей мутабельной операцией над объектом, элизия не устраняет конфликт. Нужно сократить область использования результата, изменить структуру операций или вернуть владеющее значение.