Rust Clone
用Clone来复制数据对象。
克隆Box<T>
当成员中存在Box<T>
类型的成员时,可用下面的方法来实现Clone:
use std::fmt;
struct Node {
value: u32,
next: Option<Box<Node>>,
}
impl fmt::Display for Node {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{} = ", self.value)?;
match &self.next {
Some(another) => {
another.fmt(f)
},
None => {
writeln!(f, "^")
}
}
}
}
impl Clone for Node {
fn clone(&self) -> Self {
Self {
value: self.value,
next: match &self.next {
Some(next) => Some(Box::new(*next.clone())),
None => None,
},
}
}
}
fn main() {
let n1 = Node { value: 5, next: None, };
let n2 = Node { value: 1, next: Some(Box::new(n1)), };
let n3 = Node { value: 4, next: Some(Box::new(n2)), };
let n4 = Node { value: 1, next: Some(Box::new(n3)), };
let mut n5 = Node { value: 3, next: Some(Box::new(n4)), };
let l2 = n5.clone();
n5.value = 6;
println!("list: {}", n5);
println!("l2: {}", l2);
}
克隆 Trait object
当Box内的元素是一个 Trait object时,需要用下面的方式来克隆:
use std::fmt;
////////////////////////////////////////////////////////////////////////////////
// Trait
trait Valuable: ValuableClone + fmt::Display {
fn value(&self) -> i32;
}
impl Clone for Box<dyn Valuable> {
fn clone(&self) -> Box<dyn Valuable> {
self.clone_box()
}
}
trait ValuableClone {
fn clone_box(&self) -> Box<dyn Valuable>;
}
impl<T> ValuableClone for T
where T: 'static + Valuable + Clone {
fn clone_box(&self) -> Box<dyn Valuable> {
Box::new(self.clone())
}
}
////////////////////////////////////////////////////////////////////////////////
// Struct
#[derive(Clone)]
struct Node {
value: i32,
next: Option<Box<dyn Valuable>>,
}
impl Node {
fn new(value: i32, next: Option<Box<dyn Valuable>>) -> Self {
Self {
value: value,
next: next,
}
}
fn set_next(&mut self, next: Option<Box<dyn Valuable>>) {
self.next = next;
}
}
impl Valuable for Node {
fn value(&self) -> i32 {
self.value
}
}
impl fmt::Display for Node {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{}", self.value)?;
match &self.next {
Some(next) => {
write!(f, " -> {}", *next)?;
},
None => {
write!(f, " -> ^")?;
},
}
Ok(())
}
}
impl From<i32> for Node {
fn from(value: i32) -> Self {
Node::new(value, None)
}
}
fn main() {
let mut n1 = Node::from(3);
let mut n2 = Node::from(1);
let mut n3 = Node::from(4);
n3.set_next(None);
n2.set_next(Some(Box::new(n3)));
n1.set_next(Some(Box::new(n2)));
println!("list1: {}", n1);
}