I'm following Final Code - Learning Rust With Entirely Too Many Linked Lists (rust-unofficial.github.io) to build an immutable linked list.
use std::rc::Rc;
pub struct SList<T> {
head : SLink<T>,
}
pub struct Iter<'a, T> {
next : Option<&'a SNode<T>>
}
type SLink<T> = Option<Rc<SNode<T>>>;
struct SNode<T> {
next : SLink<T>,
elem : T,
}
impl<T> SList<T> {
pub fn new() -> Self {
SList { head : None }
}
pub fn append(&self, elem: T) -> SList<T> {
SList { head:
Some(Rc::new(SNode{
next: self.head.clone(),
elem: elem,
}))}
}
pub fn head(&self) -> Option<&T> {
self.head.as_ref().map(|node| &node.elem)
}
pub fn tail(&self) -> SList<T> {
SList { head: self.head.as_ref().and_then(|node| node.next.clone()) }
}
pub fn iter(&self) -> Iter<'_, T> {
Iter { next: self.head.as_deref() }
}
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.next.map(|node| {
self.next = node.next.as_deref();
&node.elem
})
}
}
#[cfg(test)]
mod tests {
use super::SList;
#[test]
fn tail() {
let l0 = SList::<i32>::new();
let l1 = l0.append(1);
let l2 = l1.append(2);
let adder = |accu, item| { accu + item };
assert_eq!(l0.tail().iter().fold(0i32, adder), 0);
assert_eq!(l1.tail().iter().fold(0i32, adder), 0);
assert_eq!(l2.tail().iter().fold(0i32, adder), 1);
}
}
After ran cargo test
on this code, I got this error
error[E0716]: temporary value dropped while borrowed
--> src\immutable\slist.rs:65:14
|
65 | assert_eq!(l0.tail().iter().fold(0i32, adder), 0);
| -----------^^^^^^^^^------------------------------
| | |
| | creates a temporary which is freed while still in use
| temporary value is freed at the end of this statement
66 | assert_eq!(l1.tail().iter().fold(0i32, adder), 0);
| ----- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
error[E0716]: temporary value dropped while borrowed
--> src\immutable\slist.rs:66:14
|
66 | assert_eq!(l1.tail().iter().fold(0i32, adder), 0);
| -----------^^^^^^^^^------------------------------
| | |
| | creates a temporary which is freed while still in use
| temporary value is freed at the end of this statement
67 | assert_eq!(l2.tail().iter().fold(0i32, adder), 1);
| ----- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
Why there is a borrow here ? I thought l1.tail()
and l2.tail()
are completely independent.