Рассмотрим этот упрощенный код:
struct Foo {
x: i32
}
fn test(_: &'static Foo) {}
fn main() {
let f = Foo{ x: 42 };
test(&f);
}
Как и ожидалось, он не компилируется с сообщением:
f
не живет достаточно долго
Однако это небольшое изменение действительно компилируется:
fn main() {
let f = &Foo{ x: 42 };
test(f);
}
Разница в том, что в первом случае объект Foo
является локальным, с локальным временем жизни, поэтому ссылка 'static
не может быть построен. Но в последнем случае фактический объект является статической c константой, поэтому он имеет статическое c время жизни, а f
является просто ссылкой на него.
Чтобы увидеть разницу, рассмотрим этот другой эквивалентный код:
const F: Foo = Foo{ x: 42 };
fn main() {
test(&F);
}
Или, если вы используете фактический константный литерал:
fn test_2(_: &'static i32) {}
fn main() {
let i = &42;
test_2(&i);
}
Естественно, это работает, только если все аргументы конструкции Foo
постоянны. Если какое-либо значение не является константой, компилятор автоматически переключится на локальное временное значение вместо константы stati c, и вы потеряете время жизни 'static
.
Точные правила для этого постоянное продвижение , как его иногда называют, немного сложнее и может быть расширено в новых версиях компилятора.