Editor's note: The code in this question predates Rust 1.0. The equivalent modern version of this code compiles as-is.
I'm still taking baby steps at learning Rust, and was surprised at the following.
I couldn't understand why this code compiles:
use std::iter::AdditiveIterator;
fn main() {
let range = [1,2,3,4,5,6,7,8,9];
let sum = range.iter().map(|&x| x * x).filter(|&x| x % 2 == 0).sum();
println!("{}", sum);
}
While this doesn't: (just moving the .iter()
up)
use std::iter::AdditiveIterator;
fn main() {
let range = [1,2,3,4,5,6,7,8,9].iter();
let sum = range.map(|&x| x * x).filter(|&x| x % 2 == 0).sum();
println!("{}", sum);
}
Which renders this error:
test.rs:5:17: 5:36 error: borrowed value does not live long enough
test.rs:5 let range = [1,2,3,4,5,6,7,8,9].iter();
^~~~~~~~~~~~~~~~~~~
I'm sure it has something to do with Rust scopes etc, but I'm not sure I understand how by just moving the method call to a different line makes a difference.
In modern Rust, the equivalent code compiles:
fn main() {
let range = [1, 2, 3, 4, 5, 6, 7, 8, 9].iter();
let sum: i32 = range.map(|&x| x * x).filter(|&x| x % 2 == 0).sum();
println!("{}", sum);
}
This is because literals, like the array literal, are now automatically promoted to static variables if they need to be. The result of iter
here is now a std::slice::Iter<'static, i32>
.
See also:
The array gets destroyed at the end of the let range = [1,2,3,4,5,6,7,8,9].iter();
statement as there is no variable that holds that vector. This would cause a dangling iterator pointing nowhere.
The same occurs in C++, where it is possible to create iterator on object that gets deleted after.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With