advance/circle-self-ref/circle-reference #757
Replies: 24 comments 16 replies
-
First Blood |
Beta Was this translation helpful? Give feedback.
-
要扎实这块的知识,还是要尝试手写简单的 链表和树结构的实现,不能光看不练。 |
Beta Was this translation helpful? Give feedback.
-
请问有没有大佬可以通过Option<Rc<RefCell>>来实现一个双向读的链表,目前在pre往回读的时候,没办法从里面读出数据,实在很难受,希望能有大佬可以给点思路 |
Beta Was this translation helpful? Give feedback.
-
仔细想想,Rc和Weak和js的引用计数机制以及WeakMap/WeakSet好像一模一样哈哈 |
Beta Was this translation helpful? Give feedback.
-
哪位大神解释一下? |
Beta Was this translation helpful? Give feedback.
-
为什么去掉 use std::rc::Rc;
fn main() {
let five = Rc::new(5);
let weak_five = Rc::downgrade(&five);
let strong_five = weak_five.upgrade();
println!("{:?}", strong_five);
drop(five);
let strong_five = weak_five.upgrade();
println!("{:?}", strong_five);
} |
Beta Was this translation helpful? Give feedback.
-
这里,List 为啥是 RefCell<Rc>,而不是 Rc<RefCell> 呢? |
Beta Was this translation helpful? Give feedback.
-
为啥第一个例子的一对多关系用Weak指针 但是第二个例子的一对多关系反而是 Weak指针应该在什么地方使用,是以关系决定,还是都可以?只要这种双向引用关系不出现循环引用就行了 |
Beta Was this translation helpful? Give feedback.
-
看起来rust这些特性是在为自己的设计填坑,实际使用价值有没有 |
Beta Was this translation helpful? Give feedback.
-
tree那个例子为什么用ReCell<Rc<>> 而不是 Rc<RefCell<>> |
Beta Was this translation helpful? Give feedback.
-
断断续续用时了一个月看到这一章, 在编译器的各种暴击之后,终于能够自己独立的写出链表和二叉树了。 快哭了都! |
Beta Was this translation helpful? Give feedback.
-
为什么 a.tail() 会导致循环调用呢?不就是一个match 函数吗? |
Beta Was this translation helpful? Give feedback.
-
parent没有了,是不是leaf也没了存在的必要? |
Beta Was this translation helpful? Give feedback.
-
只能说干得漂亮。 use std::cell::RefCell;
use std::rc::Rc;
#[derive(Debug)]
enum List<T> {
Elem(T, RefCell<Rc<List<T>>>),
None,
}
impl<T> List<T> {
fn new(t: T) -> Rc<Self> {
Rc::new(Self::Elem(t, RefCell::new(Rc::new(List::None))))
}
fn set_next(&self, list: &Rc<List<T>>) -> Option<&RefCell<Rc<List<T>>>> {
match self {
List::Elem(_, next) => {
*next.borrow_mut() = list.clone();
Some(next)
},
_ => None,
}
}
}
fn main() {
let a = List::new("a");
let b = List::new("b");
println!("a.count = {}, b.count = {}", Rc::strong_count(&a), Rc::strong_count(&b));
b.set_next(&a);
a.set_next(&b);
println!("a.count = {}, b.count = {}", Rc::strong_count(&a), Rc::strong_count(&b));
println!("a = {:?}", a);
} |
Beta Was this translation helpful? Give feedback.
-
尝试着用这章的知识写了一个tree,并实现广度优先编历。不知道有没有办法把迭代器改为使用引用,从weak.borrow里借用出来的是一个临时引用,我没办法在迭借器里持有它。 use std::cell::RefCell;
use std::collections::linked_list::LinkedList;
use std::fmt::Debug;
use std::rc::Rc;
use std::rc::Weak;
#[derive(Debug)]
struct Node<T: Debug> {
value: T,
parent: RefCell<Weak<Node<T>>>,
children: RefCell<Vec<Rc<Node<T>>>>,
}
#[derive(Debug)]
struct NodeIterator<T: Debug> {
nodes: LinkedList<Rc<Node<T>>>,
}
impl<T: Debug> Node<T> {
fn new(value: T) -> Rc<Self> {
Rc::new(
Self {
value,
parent: RefCell::new(Weak::new()),
children: RefCell::new(Vec::new()),
}
)
}
fn add_child(self: &Rc<Self>, child: Rc<Node<T>>) {
*child.parent.borrow_mut() = Rc::downgrade(self);
self.children.borrow_mut().push(child);
}
fn iter(self: &Rc<Self>) -> NodeIterator<T> {
let mut nodes = LinkedList::new();
nodes.push_front(self.clone());
NodeIterator { nodes }
}
}
impl<T: Debug> Drop for Node<T> {
fn drop(&mut self) {
while let Some(_node) = self.children.borrow_mut().pop() {}
}
}
impl<T: Debug> Iterator for NodeIterator<T> {
type Item = Rc<Node<T>>;
fn next(&mut self) -> Option<Self::Item> {
match self.nodes.pop_back() {
Some(node) => {
node.children
.borrow()
.iter()
.all(|node| {
self.nodes.push_front(node.clone());
true
});
Some(node)
},
_ => None,
}
}
}
fn main() {
let n1 = Node::new(1);
let n11 = Node::new(11);
n11.add_child(Node::new(111));
let n12 = Node::new(12);
let n121 = Node::new(121);
n121.add_child(Node::new(1211));
n12.add_child(n121);
n12.add_child(Node::new(122));
let n13 = Node::new(13);
n13.add_child(Node::new(131));
let n132 = Node::new(132);
n132.add_child(Node::new(1321));
n13.add_child(n132);
let n133 = Node::new(133);
n133.add_child(Node::new(1331));
n133.add_child(Node::new(1332));
n133.add_child(Node::new(1333));
n13.add_child(n133);
n1.add_child(n11);
n1.add_child(n12);
n1.add_child(n13);
println!("root = {:?}\r\n\r\n", n1);
for node in n1.iter() {
println!("node = {:?}", node.value);
}
} |
Beta Was this translation helpful? Give feedback.
-
不知道我的理解对不对,所以使用weak可以防止出现循环引用并导致stack overflow的主要原因是 weak不会自动deref,所以他不会无限的被互相调用下去? |
Beta Was this translation helpful? Give feedback.
-
为什么我把第11行的assert_eq语句注释掉了,最后strong_five还是Some(5) use std::rc::Rc;
} |
Beta Was this translation helpful? Give feedback.
-
''' let p: (&i32, i32) = (&5, 0); 虽然在IDE中会告诉我答案,但是具体怎么发生的希望有大佬总结一下 |
Beta Was this translation helpful? Give feedback.
-
rc<refcell<>>可以实现赋值改变,refcell<rc<>>可以实现指向对象的改变。但是rust提供的指针功能没有可以同时改变这两者的,我只能说是坑不比cpp少到哪里去 |
Beta Was this translation helpful? Give feedback.
-
你好,您的邮件已收到,谢谢。
|
Beta Was this translation helpful? Give feedback.
-
你好,您的邮件已收到,谢谢。
|
Beta Was this translation helpful? Give feedback.
-
感觉C++工程化发展过程中踩过的坑, 各个标准的解决方案, Rust也避免不了. 这也说明理论,科学和工程的巨大鸿沟. 约学习Rust, 越觉得其像是C++ 23的一个"安全版子集". 学好Rust后, 不管使用Rust, C语言还是C++, 相信技能会大大增强, 心智负担会大大减小. Rust开发学习, 可以从娃娃抓起, 建议大学课程中可以引入Rust作为计算机学习语言,这样Rust开发人才问题会缓解一大部分.希望Rust能够为我们基础软件自主化创新贡献宝贵力量. |
Beta Was this translation helpful? Give feedback.
-
你好,您的邮件已收到,谢谢。
|
Beta Was this translation helpful? Give feedback.
-
advance/circle-self-ref/circle-reference
https://course.rs/advance/circle-self-ref/circle-reference.html
Beta Was this translation helpful? Give feedback.
All reactions