相关疑难解决方法(0)

当我可以使用Cell或RefCell时,我应该选择哪个?

std::cell文档中,我看到Cell"只与实现的类型兼容Copy".这意味着我必须使用RefCellCopy类型.

当我这样做有一个Copy类型,是否有使用一种类型的细胞在另一个好处?我假设答案是肯定的,因为否则两种类型都不存在!使用一种类型而不是另一种类型有什么好处和权衡?

这是一个愚蠢的,虚构的例子,使用两者CellRefCell实现相同的目标:

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)

rust

27
推荐指数
3
解决办法
6294
查看次数

Cell或RefCell是最佳选择的情况

您什么时候需要使用Cell或RefCell?似乎有许多其他类型选择适合代替这些,文档警告说使用RefCell是一种"最后的手段".

使用这些类型是" 代码味 "吗?任何人都可以展示一个例子,使用这些类型比使用其他类型更有意义,例如Rc甚至Box

rust interior-mutability

22
推荐指数
3
解决办法
5355
查看次数

这个错误是由于编译器对RefCell的特殊了解吗?

fn works<'a>(foo: &Option<&'a mut String>, s: &'a mut String) {}
fn error<'a>(foo: &RefCell<Option<&'a mut String>>, s: &'a mut String) {}

let mut s = "hi".to_string();

let foo = None;
works(&foo, &mut s);

// with this, it errors
// let bar = RefCell::new(None);
// error(&bar, &mut s);

s.len();
Run Code Online (Sandbox Code Playgroud)

如果我在注释中添加两行,则会发生以下错误:

error[E0502]: cannot borrow `s` as immutable because it is also borrowed as mutable
  --> <anon>:16:5
   |
14 |     error(&bar, &mut s);
   |                      - mutable borrow occurs here
15 |     
16 |     s.len(); …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

10
推荐指数
1
解决办法
140
查看次数

Rust编译器如何知道`Cell`有内部可变性?

请考虑以下代码(Playground版本):

use std::cell::Cell;

struct Foo(u32);

#[derive(Clone, Copy)]
struct FooRef<'a>(&'a Foo);

// the body of these functions don't matter
fn testa<'a>(x: &FooRef<'a>, y: &'a Foo) { x; }
fn testa_mut<'a>(x: &mut FooRef<'a>, y: &'a Foo) { *x = FooRef(y); }
fn testb<'a>(x: &Cell<FooRef<'a>>, y: &'a Foo) { x.set(FooRef(y)); }

fn main() {
    let u1 = Foo(3);
    let u2 = Foo(5);
    let mut a = FooRef(&u1);
    let b = Cell::new(FooRef(&u1));

    // try one of the following 3 statements
    testa(&a, &u2); …
Run Code Online (Sandbox Code Playgroud)

mutability rust

6
推荐指数
2
解决办法
257
查看次数