Functions
Ignoring elision, function signatures with lifetimes have a few constraints:
- any reference must have an annotated lifetime.
- any reference being returned must have the same lifetime as an input or be
static
.
Additionally, note that returning references without input is banned if it would result in returning references to invalid data. The following example shows off some valid forms of functions with lifetimes:
// One input reference with lifetime `'a` which must live// at least as long as the function.fn print_one<'a>(x: &'a i32) {println!("`print_one`: x is {}", x);}// Mutable references are possible with lifetimes as well.fn add_one<'a>(x: &'a mut i32) {*x += 1;}// Multiple elements with different lifetimes. In this case, it// would be fine for both to have the same lifetime `'a`, but// in more complex cases, different lifetimes may be required.fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) {println!("`print_multi`: x is {}, y is {}", x, y);}// Returning references that have been passed in is acceptable.// However, the correct lifetime must be returned.fn pass_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x }//fn invalid_output<'a>() -> &'a String { &String::from("foo") }// The above is invalid: `'a` must live longer than the function.// Here, `&String::from("foo")` would create a `String`, followed by a// reference. Then the data is dropped upon exiting the scope, leaving// a reference to invalid data to be returned.fn main() {let x = 7;let y = 9;print_one(&x);print_multi(&x, &y);let z = pass_x(&x, &y);print_one(z);let mut t = 3;add_one(&mut t);print_one(&t);}