Rust标准库中有几种包装类型:
std::cell模块中的单元格:Cell和RefCellRc和Arc.std::sync模块中的类型:Mutex或者AtomicBool例如据我了解,这些是包装器,提供了比简单参考更多的可能性.虽然我理解一些基础知识,但我看不到整体情况.
他们到底做了什么?细胞和参考计数家族是否提供正交或类似的特征?
从std::cell文档中,我看到Cell"只与实现的类型兼容Copy".这意味着我必须使用RefCell非Copy类型.
当我这样做有一个Copy类型,是否有使用一种类型的细胞在另一个好处?我假设答案是肯定的,因为否则两种类型都不存在!使用一种类型而不是另一种类型有什么好处和权衡?
这是一个愚蠢的,虚构的例子,使用两者Cell并RefCell实现相同的目标:
use std::cell::{Cell,RefCell};
struct ThingWithCell {
counter: Cell<u8>,
}
impl ThingWithCell {
fn new() -> ThingWithCell {
ThingWithCell { counter: Cell::new(0) }
}
fn increment(&self) {
self.counter.set(self.counter.get() + 1);
}
fn count(&self) -> u8 { self.counter.get() }
}
struct ThingWithRefCell {
counter: RefCell<u8>,
}
impl ThingWithRefCell {
fn new() -> ThingWithRefCell {
ThingWithRefCell { counter: RefCell::new(0) }
}
fn …Run Code Online (Sandbox Code Playgroud) 您什么时候需要使用Cell或RefCell?似乎有许多其他类型选择适合代替这些,文档警告说使用RefCell是一种"最后的手段".
使用这些类型是" 代码味 "吗?任何人都可以展示一个例子,使用这些类型比使用其他类型更有意义,例如Rc甚至Box?
Rust 文档涵盖的范围Rc<RefCell<T>>非常广泛,但没有RefCell<Rc<T>>涉及我现在遇到的 。
这些是否有效地给出了相同的结果?它们之间有重要区别吗?
我正在尝试在Rust中使用线程之间共享一个可变对象Arc,但是我收到了这个错误:
error[E0596]: cannot borrow data in a `&` reference as mutable
--> src/main.rs:11:13
|
11 | shared_stats_clone.add_stats();
| ^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
Run Code Online (Sandbox Code Playgroud)
这是示例代码:
use std::{sync::Arc, thread};
fn main() {
let total_stats = Stats::new();
let shared_stats = Arc::new(total_stats);
let threads = 5;
for _ in 0..threads {
let mut shared_stats_clone = shared_stats.clone();
thread::spawn(move || {
shared_stats_clone.add_stats();
});
}
}
struct Stats {
hello: u32,
}
impl Stats {
pub fn new() -> Stats {
Stats { hello: 0 …Run Code Online (Sandbox Code Playgroud) 我需要在几个使用闭包作为参数的函数之间传递资源.并且在这些数据中处理了数据,但它查找了变量实现的变化将反映在其余部分中.
我认为首先要使用的是Rc.我以前用过Arc处理不同线程之间的数据,但由于这些函数没有在不同的线程中运行,我选择了Rc.
我有最简化的代码,以表达我的疑虑:
使用RefCell是因为我可能必须看到这种语法不会像我预期的那样工作:
*Rc::make_mut(&mut rc_pref_temp)...
Run Code Online (Sandbox Code Playgroud)
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() += …Run Code Online (Sandbox Code Playgroud)