Rust 尝试从RefCell中包装的结构借用2个字段时出错
我有一个包含数据的结构和一个最终将用于写入数据的writer。结构被包装在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
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