今天在寫rust的時候發現了一個RefCell的使用場景,就是在b持有a的所有權,而a的可變方法中又借用b的時候,這么寫是通不過借用檢查的:
struct Foo;
struct Bar {
foo: Foo,
msg: String,
}
impl Foo {
fn foo(&mut self, bar: &Bar) {
println!("{}", bar.msg);
}
}
impl Bar {
fn new(foo: Foo) -> Self {
Self {
foo,
msg: String::from("Baaaaaar"),
}
}
fn bar(&mut self) {
self.foo.foo(self);
}
}
fn main() {
let mut bar = Bar::new(Foo);
bar.bar();
}
CSDN沒有Rust的高亮,就這么著吧
playground
但是用了RefCell,就可以編譯通過了,
use core::cell::RefCell;
// 省略...
struct Bar {
foo: RefCell<Foo>,
msg: String,
}
// 省略...
impl Bar {
fn new(foo: Foo) -> Self {
Self {
foo: RefCell::new(foo),
msg: String::from("Baaaaaar"),
}
}
fn bar(&mut self) {
self.foo.borrow_mut().foo(self);
}
}
playground
可能的發生的不安全情況是這樣“套娃”
impl Foo {
fn foo(&mut self, bar: &Bar) {
println!("{}", bar.msg);
let _ = bar.foo.borrow_mut();
}
}
會產生這樣的運行時錯誤(panic):
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 0.66s
Running `target/debug/playground`
thread 'main' panicked at 'already borrowed: BorrowMutError', src/main.rs:13:25
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
因此使用的時候需要注意一下,(不是編譯通過就萬事大吉了
比如把foo欄位設為私有,bar方法設為私有什么的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/209124.html
標籤:其他
下一篇:測驗題15(答案詳析)
