reference rust borrow-checker

reference - ¿Por qué puedo devolver una referencia a un literal local pero no a una variable?



rust borrow-checker (1)

En su ejemplo, [1, 2, 3] no se trata como una variable local, sino como una variable estática.

Echemos un vistazo a este código:

fn foo() -> &''static [i32] { &[1, 2, 3] }

¡Esto funciona!

Hace algún tiempo, RFC 1414: Rvalue Static Promotion se fusionó: "Promover valores constexpr a valores en memoria estática en lugar de ranuras de pila". Esto significa que básicamente todos los literales que escribes pueden vivir para siempre. Por lo tanto, cosas como let _: &''static i32 = &42; ¡Además trabajo!

Si evitamos usar una matriz literal, podemos ver el error esperado:

fn bar() -> impl Iterator<Item = i32> { vec![1, 2, 3].iter().map(|&i| i) }

Aquí obtenemos el error " v no vive lo suficiente".

Esto no está limitado a enteros o matrices; se aplica ampliamente a cualquier literal que se compone únicamente de literales:

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'') }

Más allá de los literales, esto también funciona para una pequeña cantidad de funciones en la biblioteca estándar, pero probablemente fueron un error . Decidir si el resultado de las funciones const arbitrarias se puede promocionar automáticamente a static sigue siendo un tema abierto .

¿Por qué se compila este código?

fn get_iter() -> impl Iterator<Item = i32> { [1, 2, 3].iter().map(|&i| i) } fn main() { let _it = get_iter(); }

[1, 2, 3] es una variable local y iter() toma prestada. Este código no debe compilarse porque el valor devuelto contiene una referencia a una variable local.