Rust 尝试从RefCell中包装的结构借用2个字段时出错

Rust 尝试从RefCell中包装的结构借用2个字段时出错,rust,Rust,我有一个包含数据的结构和一个最终将用于写入数据的writer。结构被包装在RefCell中。这是一个小复制品: use std::cell::RefCell; use std::io::Write; struct Data { string: String, } struct S { data: Data, writer: Vec<u8>, } fn write(s: RefCell<S>) { let mut mut_s = s.b

我有一个包含数据的结构和一个最终将用于写入数据的writer。结构被包装在
RefCell
中。这是一个小复制品:

use std::cell::RefCell;
use std::io::Write;

struct Data {
    string: String,
}

struct S {
    data: Data,
    writer: Vec<u8>,
}

fn write(s: RefCell<S>) {
    let mut mut_s = s.borrow_mut();
    let str = &mut_s.data.string;
    mut_s.writer.write(str.as_bytes());
}

我应该使用不同的API吗

您可以手动调用
DerefMut
,然后保存结果引用:

fn write(s: RefCell<S>) {
    let mut mut_s = s.borrow_mut();
    let mut tmp = &mut *mut_s; // Here
    let str = &tmp.data.string;
    tmp.writer.write(str.as_bytes());
}
Rust不会跟踪跨函数调用的字段级借用(即使对于
Deref::Deref
DerefMut::DerefMut
)。这会导致错误,因为在从上一个
deref::deref
进行未完成借用期间,需要调用
deref\u mut
方法

带有显式借用的扩展版本如下所示,只需调用一次
Deref::Deref_mut

use std::cell::RefMut;
use std::ops::DerefMut;

fn write(s: RefCell<S>) {
    let mut mut_s: RefMut<S> = s.borrow_mut();
    let tmp: &mut S = DerefMut::deref_mut(&mut mut_s);
    let str = &tmp.data.string;
    tmp.writer.write(str.as_bytes());
}
使用std::cell::RefMut;
使用std::ops::DerefMut;
fn写入(s:RefCell){
让mut mut_s:RefMut=s.borrow_mut();
设tmp:&mut S=DerefMut::deref_mut(&mut mut_S);
让str=&tmp.data.string;
tmp.writer.write(str.as_bytes());
}
然后,编译器可以跟踪从该临时值借用的两个值是否不相交


请注意,此问题并非
RefCell
独有的问题!实现的任何类型都可能遇到相同的问题。以下是标准库中的一些:

  • MutexGuard
    (来自)
  • peek mut
    (来自)
  • RwLockWriteGuard
    (来自)
  • String
  • Vec

您可以手动调用
DerefMut
,然后保存生成的引用:

fn write(s: RefCell<S>) {
    let mut mut_s = s.borrow_mut();
    let mut tmp = &mut *mut_s; // Here
    let str = &tmp.data.string;
    tmp.writer.write(str.as_bytes());
}
Rust不会跟踪跨函数调用的字段级借用(即使对于
Deref::Deref
DerefMut::DerefMut
)。这会导致错误,因为在从上一个
deref::deref
进行未完成借用期间,需要调用
deref\u mut
方法

带有显式借用的扩展版本如下所示,只需调用一次
Deref::Deref_mut

use std::cell::RefMut;
use std::ops::DerefMut;

fn write(s: RefCell<S>) {
    let mut mut_s: RefMut<S> = s.borrow_mut();
    let tmp: &mut S = DerefMut::deref_mut(&mut mut_s);
    let str = &tmp.data.string;
    tmp.writer.write(str.as_bytes());
}
使用std::cell::RefMut;
使用std::ops::DerefMut;
fn写入(s:RefCell){
让mut mut_s:RefMut=s.borrow_mut();
设tmp:&mut S=DerefMut::deref_mut(&mut mut_S);
让str=&tmp.data.string;
tmp.writer.write(str.as_bytes());
}
然后,编译器可以跟踪从该临时值借用的两个值是否不相交


请注意,此问题并非
RefCell
独有的问题!实现的任何类型都可能遇到相同的问题。以下是标准库中的一些:

  • MutexGuard
    (来自)
  • peek mut
    (来自)
  • RwLockWriteGuard
    (来自)
  • String
  • Vec