Replies: 24 comments 37 replies
-
我很善变,还拥有多个主人 我被这里的代码示例笑喷了,真形像。 |
Beta Was this translation helpful? Give feedback.
-
但我代表它( RefCell )给你的赞绝对始终如一 :P |
Beta Was this translation helpful? Give feedback.
-
由于 所以,实现 内部可变性 的 |
Beta Was this translation helpful? Give feedback.
-
关于rc和refcell联合使用的例子在我本地的环境下无法运行,错误信息如下
请问是什么原因导致的呢?我的本地版本如下
|
Beta Was this translation helpful? Give feedback.
-
Cell 指针存放在栈上? |
Beta Was this translation helpful? Give feedback.
-
感觉最后一个例子遍历集合的同时修改集合,容易出bug fn is_even(i: &i32) -> bool {
i % 2 == 0
}
fn retain_even(nums: &mut Vec<i32>) {
let mut vec: Vec<i32> = nums
.iter()
.filter(|num| is_even(num))
.copied()
.collect();
nums.clear();
nums.append(&mut vec);
} |
Beta Was this translation helpful? Give feedback.
-
对于 #[test]
fn test_rc_RefCell(){
let s1 = Rc::new(RefCell::new(String::from("test")));
let s2 = Rc::clone(&s1);
// let mut s3 = s2.borrow_mut();
// s3.push_str(" rc+refCell");
s2.borrow_mut().push_str(" rc+refCell");
println!("{:?}", s2);
println!("{:?}", s1);
} 这样直接打印是可以打印出来的,但是如果使用了
|
Beta Was this translation helpful? Give feedback.
-
那是因为s2的借用转给了s3,s3的作用域到最后的括号,所以s1,s2 是borrowed
…------------------ 原始邮件 ------------------
发件人: ***@***.***>;
发送时间: 2023年1月2日(星期一) 晚上9:19
收件人: ***@***.***>;
抄送: ***@***.***>; ***@***.***>;
主题: Re: [sunface/rust-course] advance/smart-pointer/cell-refcell (Discussion #617)
对于Rc+RefCell组合的问题,这两种情况为什么打印的不一样?
#[test] fn test_rc_RefCell(){ let s1 = Rc::new(RefCell::new(String::from("test"))); let s2 = Rc::clone(&s1); // let mut s3 = s2.borrow_mut(); // s3.push_str(" rc+refCell"); s2.borrow_mut().push_str(" rc+refCell"); println!("{:?}", s2); println!("{:?}", s1); }
这样直接打印是可以打印出来的,但是如果使用了s3就打印不出来
是这样
RefCell { value: <borrowed> } RefCell { value: <borrowed> }
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
提一个不成熟的观点。虽然 Cell 和 RefCell 看起来可以破坏Rust的借用和可变不可变的规则,但事实上,我们如果把它们和“纯粹”的变量和变量引用放到一起理解会造成困扰。而如果仅仅把它们看做是一种特殊的“容器”,把它们的特性理解为语言核心之外的一种“外部库函数”,这样理解起来就非常清晰了。 |
Beta Was this translation helpful? Give feedback.
-
现在版本 Cell::new是可以生成值。只是某些方法要求T:Copy |
Beta Was this translation helpful? Give feedback.
-
“Cell 和 RefCell 在功能上没有区别,区别在于 Cell 适用于 T 实现 Copy 的情况:" 现在对于非Copy的类型也可以replace或者swap了 |
Beta Was this translation helpful? Give feedback.
-
let c = Cell::new("asdf");
let one = c.get();
c.set("qwer");
let two = c.get();
println!("{},{}", one, two); 为啥 c前面不加mut,c.set可以编译通过? |
Beta Was this translation helpful? Give feedback.
-
Cell 对 T 的约束只有 ?Sized, 所以 Cell 是可以的
这里并不会报错, 除非调用 |
Beta Was this translation helpful? Give feedback.
-
看起来下面第2,3种写法有安全问题,实际会用这样的写法吗 {
#[derive(Debug, Clone, Copy)]
pub struct Foo {
a: u32,
}
let x = Cell::new(Foo { a: 12 });
let y = &x;
let z = &x;
x.set(Foo { a: 13 });
y.set(Foo { a: 14 });
print!("{:?}", y.get());
print!("{:?}", x.get());
print!("{:?}", z.get());
}
{
#[derive(Debug)]
pub struct Foo {
a: u32,
}
let x = Cell::new(&Foo { a: 12 });
let y = &x;
let z = &x;
x.set(&Foo { a: 13 });
y.set(&Foo { a: 14 });
print!("{:?}", x.get());
print!("{:?}", y.get());
print!("{:?}", z.get());
}
{
#[derive(Debug)]
pub struct Foo {
a: u32,
}
let x = Rc::new(RefCell::new(Foo { a: 12 }));
let y = Rc::clone(&x);
let z = Rc::clone(&x);
// 在 Mutex 中进行修改
*x.borrow_mut() = Foo { a: 13 };
*y.borrow_mut() = Foo { a: 14 };
// 在 Mutex 中获取值
let x_value = x.borrow();
let y_value = y.borrow();
let z_value = z.borrow();
println!("{:?}", *x_value);
println!("{:?}", *y_value);
println!("{:?}", *z_value);
} |
Beta Was this translation helpful? Give feedback.
-
对于let c =Cell::new(String::from("wadad"));这一行,编译器没有报错,推测是因为Rust的惰性初始化,而且第二行把第一行的c给覆盖了,所以后续没有报错 |
Beta Was this translation helpful? Give feedback.
-
第一个例子中,有没有 Cell 不是一样吗 fn main() {
let mut c = "asdf";
let one = c;
c = "qwer";
let two = c;
println!("{},{}", one, two);
} |
Beta Was this translation helpful? Give feedback.
-
读完 只被调用一次的函数 @ 4.6.2 才发现 Cell 可以让 unsafe 的可变静态全局变量变成 safe:
|
Beta Was this translation helpful? Give feedback.
-
use std::cell::RefCell;
} 我觉得这个例子举的不够好,因为之前说了RefCell只是避免了编译器的可变和不可变的冲突,但是运行时会检查的。然后我修改了一下代码
} |
Beta Was this translation helpful? Give feedback.
-
RefCell 关注点在为一个无论是否可变的类型(变量/值),对外提供该类型的不可变引用和可变引用,这里是 unsafe 的实现,不受借用规则限制。 |
Beta Was this translation helpful? Give feedback.
-
有一个问题, 如何在下面的代码中调用 struct MsgQueue {
msg_cache: std::cell::RefCell<Vec<String>>,
// msg_cache: &'a mut Vec<String>
}
// impl<'a> MsgQueue<'a> {
impl MsgQueue {
fn cache(&mut self, s: String)
{
self.msg_cache.borrow_mut().push(s);
}
}
impl Messenger for MsgQueue {
fn send(&self, msg: String) {
// 这样写是错误的 self.cache(msg);
}
} 而且发现 |
Beta Was this translation helpful? Give feedback.
-
只能说 兜兜转转 回到了 c++,没有所谓的安全,只有相对安全,通过编译器解决内存安全不是银弹,更多的还是理解内存管理和如何安全的操作内存! |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
手写了一个refcell的例子
|
Beta Was this translation helpful? Give feedback.
-
https://course.rs/advance/smart-pointer/cell-refcell.html
Beta Was this translation helpful? Give feedback.
All reactions