【发布时间】:2017-05-16 22:24:03
【问题描述】:
我需要在几个使用闭包作为参数的函数之间传递资源。在这些数据中处理了数据,但它会寻找对变量实现的更改将反映在其余部分中。
我首先想到的是使用Rc。我之前使用Arc 来处理不同线程之间的数据,但由于这些函数不在不同的线程中运行,所以我选择了Rc。
我拥有的最简化的代码,以表达我的疑问:
RefCell 的使用是因为也许我必须看到这个语法不会像我预期的那样工作:
*Rc::make_mut(&mut rc_pref_temp)...
use std::sync::Arc;
use std::rc::Rc;
use std::sync::Mutex;
use std::cell::RefCell;
use std::cell::Cell;
fn main() {
test2();
println!("---");
test();
}
#[derive(Debug, Clone)]
struct Prefe {
name_test: RefCell<u64>,
}
impl Prefe {
fn new() -> Prefe {
Prefe {
name_test: RefCell::new(3 as u64),
}
}
}
fn test2(){
let mut prefe: Prefe = Prefe::new();
let mut rc_pref = Rc::new(Mutex::new(prefe));
println!("rc_pref Mutex: {:?}", rc_pref.lock().unwrap().name_test);
let mut rc_pref_temp = rc_pref.clone();
*rc_pref_temp.lock().unwrap().name_test.get_mut() += 1;
println!("rc_pref_clone Mutex: {:?}", rc_pref_temp.lock().unwrap().name_test);
*rc_pref_temp.lock().unwrap().name_test.get_mut() += 1;
println!("rc_pref_clone Mutex: {:?}", rc_pref_temp.lock().unwrap().name_test);
println!("rc_pref Mutex: {:?}", rc_pref.lock().unwrap().name_test);
}
fn test(){
let mut prefe: Prefe = Prefe::new();
let mut rc_pref = Rc::new(prefe);
println!("rc_pref: {:?}", rc_pref.name_test);
let mut rc_pref_temp = rc_pref.clone();
*((*Rc::make_mut(&mut rc_pref_temp)).name_test).get_mut() += 1;
println!("rc_pref_clone: {:?}", rc_pref_temp.name_test);
*((*Rc::make_mut(&mut rc_pref_temp)).name_test).get_mut() += 1;
println!("rc_pref_clone: {:?}", rc_pref_temp.name_test);
println!("rc_pref: {:?}", rc_pref.name_test);
}
代码简化,使用场景完全不同。我注意到这一点是为了避免诸如“您可以为函数提供价值”之类的 cmets,因为我感兴趣的是知道为什么暴露的案例以这种方式工作。
标准输出:
rc_pref Mutex : RefCell { value: 3 }
rc_pref_clone Mutex : RefCell { value: 4 }
rc_pref_clone Mutex : RefCell { value: 5 }
rc_pref Mutex : RefCell { value: 5 }
---
rc_pref : RefCell { value: 3 }
rc_pref_clone : RefCell { value: 4 }
rc_pref_clone : RefCell { value: 5 }
rc_pref : RefCell { value: 3 }
关于test()
我是 Rust 新手,所以我不知道这种疯狂的语法是否正确。
*((*Rc::make_mut(&mut rc_pref_temp)).name_test).get_mut() += 1;
运行test() 时,您可以看到前面的语法有效,因为它增加了值,但这种增加不会影响克隆。我希望通过使用*Rc::make_mut(& mut rc_pref_temp)...,共享引用的克隆将反映相同的值。
- 如果
Rc引用了同一个对象,为什么对一个对象所做的更改不适用于其余的克隆?为什么会这样?我做错了什么吗?
注意:我使用RefCell 是因为在某些测试中我认为也许我有事要做。
关于test2()
我已经使用Mutex 和Rc 让它按预期工作,但我不知道这是否是正确的方法。我对Mutex 和Arc 的工作原理有一些想法,但是在使用此语法之后:
*Rc::make_mut(&mut rc_pref_temp)...
在test2()中使用Mutex,我想知道Mutex是否不仅负责更改数据,还负责反映所有克隆引用的更改。
共享引用实际上指向同一个对象吗?我想他们会这样做,但是对于上面的代码,如果不使用Mutex,更改不会反映出来,我有一些疑问。
【问题讨论】:
标签: rust