cannot return value referencing temporary value returns a value referencing data owned by the current function
Box
A pointer type for heap allocation. Box<T>, casually referred to as a ‘box’, provides the simplest form of heap allocation in Rust. Boxes provide ownership for this allocation, and drop their contents when they go out of scope.
Box是在堆上分配的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
enumList<T> { Cons(T, Box<List<T>>), Nil, }
impl List<u32> { fnrange(l: i32, h: i32) -> List<i32> { if l < h { List::Cons(l, Box::new(List::range(l + 1, h))) } else { List::Nil } } }
error[E0507]: cannot move out of `self.0.1` which is behind a mutable reference --> src/main.rs:21:15 | 21 | matchself.0 { | ^^^^^^ help: consider borrowing here: `&self.0` 22 | List::Cons(item,rest) => { | ---- | | | data moved here | move occurs because `rest` has type `std::boxed::Box<List<T>>`, which does not implement the `Copy` trait ^^^^ ^^^^
error[E0495]: cannot infer an appropriate lifetime for pattern due to conflicting requirements --> src/main.rs:54:24 | 54 | List::Cons(item,rest) =>{ | ^^^^ | note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 52:5... --> src/main.rs:52:5 | 52 | fn next(&mut self) -> Option<Self::Item> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...so that reference does not outlive borrowed content --> src/main.rs:54:24 | 54 | List::Cons(item,rest) =>{ | ^^^^ note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 49:6... --> src/main.rs:49:6 | 49 | impl<'a,T> Iterator for IterMut<'a,T>{ | ^^ note: ...so that the types are compatible --> src/main.rs:52:46 | 52 | fn next(&mut self) -> Option<Self::Item> { | ______________________________________________^ 53 | | match self.0 { 54 | | List::Cons(item,rest) =>{ 55 | | self.0 = rest.as_mut(); ... | 63 | | } 64 | | } | |_____^ = note: expected `Iterator` found `Iterator` error[E0495]: cannot infer an appropriate lifetime for pattern due to conflicting requirements --> src/main.rs:54:29 | 54 | List::Cons(item,rest) =>{ | ^^^^ | note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 52:5... --> src/main.rs:52:5 | 52 | fn next(&mut self) -> Option<Self::Item> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...so that reference does not outlive borrowed content --> src/main.rs:54:29 | 54 | List::Cons(item,rest) =>{ | ^^^^ note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 49:6... --> src/main.rs:49:6 | 49 | impl<'a,T> Iterator for IterMut<'a,T>{ | ^^ note: ...so that reference does not outlive borrowed content --> src/main.rs:55:26 | 55 | self.0 = rest.as_mut(); | ^^^^^^^^^^^^^
fnmain() { let x = List::range(1, 100_000_000).into_iter().fold(0, |_,a| a); print!("{}", x) }
1 2 3
Finished dev [unoptimized + debuginfo] target(s) in 0.46s Running `target/debug/temp` 100000000%
没有问题
1 2 3 4
fnmain() { let x = List::range(1, 100_000_000).iter().fold(0, |_,a| *a); print!("{}", x) }
💥Boom
1 2 3
thread 'main' has overflowed its stack fatal runtime error: stack overflow [1] 15047 abort (core dumped) cargo run
调试一下 递归drop爆栈,而第一段不爆是因为手动展开了
After drop is run, Rust will recursively try to drop all of the fields of self. This is a convenience feature so that you don’t have to write “destructor boilerplate” to drop children. If a struct has no special logic for being dropped other than dropping its children, then it means Drop doesn’t need to be implemented at all! There is no stable way to prevent this behavior in Rust 1.0.