Option itself has a copy trait, but its behaviors depends on what it hold.
#[derive(Copy, PartialOrd, Eq, Ord, Debug, Hash)]
#[rustc_diagnostic_item = "Option"]
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Option<T> {
/// No value.
#[lang = "None"]
#[stable(feature = "rust1", since = "1.0.0")]
None,
/// Some value of type `T`.
#[lang = "Some"]
#[stable(feature = "rust1", since = "1.0.0")]
Some(#[stable(feature = "rust1", since = "1.0.0")] T),
}
Example
let x = Some(5);
let y = x; // copy x not move x
println!("{:?}", x);
let x = Some(Box::new(5));
let y = x; // moved here
println!("{:?}", x); // compile error
So, when iterating over a linked list, you should use node.next.as_ref()
rather than (&node.next).as_ref()
#[derive(Debug)]
struct Node {
value: i32,
next: Option<Box<Node>>,
}
fn main() {
let mut head = Box::new(Node { value: 0, next: None });
let second = Box::new(Node { value: 1, next: None });
head.next = Some(second);
let mut u = Some(&head);
while let Some(v) = u {
print!("{}->", v.value);
// (&v.next).as_ref() is too verbose
u = v.next.as_ref();
}
println!("None");
println!("{:?}", &head);
}
What as_ref does is take in Option<T>
, then make it Option<&T>
. This behavior cause a copy not move.
#[inline]
#[rustc_const_stable(feature = "const_option_basics", since = "1.48.0")]
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn as_ref(&self) -> Option<&T> {
match *self {
Some(ref x) => Some(x),
None => None,
}
}
Top comments (0)