Необходимость указания времени жизни в Rust когда компилятор может вывести время жизни сам
Почему этот код вызывает ошибку:
const MSG: &str = "Hello";
fn one_of(_first: &str, _second: &str) -> &str {
MSG
}
Задал это вопрос своему железному другу (gpt-4-1106-preview) и он ответил:
Код вызывает ошибку, потому что Rust не может гарантировать, что строка, на которую ссылается
MSG, будет жить достаточно долго, чтобы безопасно использовать возвращаемую ссылку из функцииone_of
Ну, ладно, допустим, тогда почему эта функция НЕ вызывает ошибку:
const MSG: &str = "Hello";
fn one(_first: &str) -> &str {
MSG
}
Мой друг ответил:
Когда функция
oneобъявлена без явного указания времени жизни для возвращаемой ссылки, компилятор использует вывод времени жизни и видит, что возвращаемое значениеMSGимеет статическое время жизни. В результате компилятор считает, что функция возвращает ссылку со статическим временем жизни, и этот вывод совместим с временем жизни входного параметра (который в данном случае игнорируется, так как не используется для определения времени жизни возвращаемого значения).
на мое резонное возражение:
но ведь и вслучае one_of компилятор может автоматически присвоить функции статическое время жизни, как и в случае one, почему все, что ты сказал по поводу one недействительно в случае с функцией one_of?
Мой друг окончательно сломался, начал извиняться "за путаницу", и заявил, что обе функции не должны вызывать ошибку (хотя, это не так).
Требуется помощь биологических нейросетей, то есть вас, уважаемые кожаные и костистые друзья! Объясните сабж
Ответы (1 шт):
Когда функция возвращает ссылку, компилятор должен знать её время жизни. Под "знать" понимается "определить время жизни ссылки по сигнатуре функции" без исследования тела функции. Во имя сохранения труда программистов в Rust придумали правила неявного выведения времени жизни возвращаемого значения.
В данном случае функция получает на вход две разных ссылки, компилятор не решается определить, к времени жизни какой из них нужно привязать время жизни возвращаемой ссылки. Требуется подсказать ему, например так:
fn one_of<'a>(_first: &'a str, _second: &'a str) -> &'a str {
MSG
}