В вашем примере [1, 2, 3]
не обрабатывается как локальная переменная, а как статическая!
Давайте посмотрим на этот код:
fn foo() -> &'static [i32] {
&[1, 2, 3]
}
Это работает!
Некоторое время назад, RFC 1414: Rvalue Static Promotion было объединено: «Повышать значения constexpr для значений в статической памяти вместо слотов стека».Это означает, что в основном все написанные вами литералы могут жить вечно.Таким образом, такие вещи, как let _: &'static i32 = &42;
также работают!
Если мы избегаем использования литерального массива, мы можем увидеть ожидаемую ошибку:
fn bar() -> impl Iterator<Item = i32> {
vec![1, 2, 3].iter().map(|&i| i)
}
Здесь мы получаем "v
неошибка "живи достаточно долго".
Это не ограничивается целыми числами или массивами;это широко применяется к любому литералу, который состоит исключительно из литералов:
fn promote_integer() -> &'static i32 {
&42
}
fn promote_float() -> &'static f64 {
&42.42
}
fn promote_str() -> &'static str {
"Hello World!"
}
struct Foo(char);
fn promote_struct() -> &'static Foo {
&Foo('x')
}
Помимо литералов, это также работает для крошечного числафункций в стандартной библиотеке, , но они, вероятно, были ошибкой .Решение о том, может ли результат произвольных const
функций быть автоматически повышен до static
, все еще является открытой темой .