编写一个简单链表,主要遇到的问题就是next指针(按照C的写法)的数据如何定义。按照网上的建议,一般定义如下:
struct Node {
pub value:u32,
pub next:Option<Rc<RefCell<Node>>>, //1
}
1.用Option主要是用None/Some来区分next节点是否有数据。RC是用来做智能支持来计数,防止被move后变量无法使用。RefCell是为了让RC的数据可写。
使用这个数据结构,基本上写代码没什么问题。目前我就遇到一个比较神奇的问题:使用borrow_mut之后,无法找到成员变量..
但是实际上上面类似的代码却能找到对应的成员变量。仔细对比了2个borrow_mut函数,你会发现,我去,完全是2个接口~
出现问题的时候的borrow_mut接口:
正常情况下:
一个是BorrowMut,一个是RefCell的。具体什么原因导致出现这样的问题?不知道,哈哈,我们先看一下怎么去解决这个问题。
我们发现,try_borrow_mut貌似只有refcell实现了,所以这个接口返回的是我们需要的值RefMut<>,但是注意一下,由于try_borrow_mut返回的是result,所以我们还需要unwrap一下。
这样就能愉快的使用了。附上简单的链表代码
use std::borrow::BorrowMut;
use std::rc::Rc;
use std::cell::RefCell;
struct Node {
pub value:u32,
pub next:Option<Rc<RefCell<Node>>>,
}
impl Node {
pub fn new(v:u32)->Self {
Node {
value:v,
next:None,
}
}
}
pub struct LinkedList {
head:Option<Rc<RefCell<Node>>>
}
impl LinkedList {
pub fn new()->Self {
LinkedList{
head:None,
}
}
pub fn push(&mut self,value:u32) {
if let Some(ref mut head) = self.head.clone() {
let mut prev: Rc<RefCell<Node>> = head.clone();
let mut current = head.clone();
let mut pos :u32 = 0;
loop {
if current.borrow().value < value {
if pos == 0 {
let mut newhead = Node::new(value);
newhead.next = Some(current.clone());
self.head = Some(Rc::new(RefCell::new(newhead)));
break;
} else {
let mut newhead = Node::new(value);
newhead.next = Some(current.clone());
prev.try_borrow_mut().unwrap().next = Some(Rc::new(RefCell::new(newhead)));
break;
}
} else {
prev = current.clone();
let tmp = current.try_borrow_mut().unwrap().next.take().unwrap();
current = tmp;
pos = pos + 1;
}
}
} else {
self.head = Some(Rc::new(RefCell::new(Node::new(value))));
}
}
pub fn dump(&self) {
let mut p: Option<Rc<RefCell<Node>>> = self.head.clone();
loop {
match p {
None=> {
println!("end");
return;
},
Some(v) => {
let v1 = v.clone().try_borrow_mut().unwrap().value;
println!("value is {}",v1);
p = v.clone().try_borrow_mut().unwrap().next.clone();
}
}
}
}
}