难点:
- 如何在所有权变更的情况下获取节点的引用
- 获取引用之后如何对其值进行修改并确认内存中的值也同步修改
关键方法
as_mut() 说明:该方法创建一个结构体对象的可变引用,当这个引用可以对结构体对象进行数据修改
as_ref() 说明:该方法创建一个新的引用,相当于copy了一份引用。修改该引用时不会修改之前的结构体对象的数据
代码
type TNode = Option<Box<Node>>;
#[derive(Debug)]
struct Node {
data: i32,
next: TNode,
}
#[derive(Debug)]
struct TList {
head: TNode,
}
impl TList {
pub fn new() -> Self {
TList { head: None }
}
pub fn push(&mut self, data: i32) {
if self.head.is_none() {
self.head = Some(Box::new(Node { data, next: None }));
return;
}
let last_node = self.get_last();
last_node.next = Some(Box::new(Node { data, next: None }));
}
pub fn get_last(&mut self) -> &mut Box<Node> {
let mut first_node = self.head.as_mut().unwrap();
loop {
if first_node.next.is_none() {
return first_node;
} else {
first_node = first_node.next.as_mut().unwrap();
}
}
}
pub fn pop(&mut self) {
if self.head.is_none() {
return;
}
let mut first_node = self.head.as_mut().unwrap();
if first_node.next.is_none() {
self.head.take();
return;
}
loop {
if first_node.next.as_mut().unwrap().next.is_none() {
first_node.next = None;
return;
} else {
first_node = first_node.next.as_mut().unwrap();
}
}
}
pub fn find(&self, data: i32) -> Option<&Box<Node>> {
if self.head.is_none() {
return None;
}
let mut node = self.head.as_ref().unwrap();
loop {
if node.data.eq(&data) {
return Some(node);
} else {
if node.next.is_none() {
return None;
} else {
node = node.next.as_ref().unwrap();
}
}
}
}
pub fn print_list(&self) {
let mut first_node = self.head.as_ref().unwrap();
loop {
if first_node.next.is_none() {
println!("当前节点值: {}", first_node.data);
return;
} else {
println!("当前节点值: {}", first_node.data);
first_node = first_node.next.as_ref().unwrap();
}
}
}
}
pub fn run() {
let mut list = TList::new();
list.push(1);
list.push(2);
list.push(3);
list.push(4);
println!("{:#?}\n", list.find(9));
// list.print_list();
}
// 结果
TList {
head: Some(
Node {
data: 1,
next: Some(
Node {
data: 2,
next: Some(
Node {
data: 3,
next: Some(
Node {
data: 4,
next: None,
},
),
},
),
},
),
},
),
}