Rust 在编译时提供借用检查。但如果使用Rc
and RefCell
,检查将在运行时推迟,并且当程序违反规则时将引发恐慌。像这样:
use std::rc::Rc;
use std::cell::RefCell;
fn func1(reference: Rc<RefCell<String>>){
let mut a = reference.borrow_mut();
*a = String::from("func1");
func2(reference.clone());
}
fn func2(reference: Rc<RefCell<String>>){
let mut a = reference.borrow_mut();
*a = String::from("func2");
func3(reference.clone());
}
fn func3(reference: Rc<RefCell<String>>){
let mut a = reference.borrow_mut();
*a = String::from("func3");
}
fn main() {
let a = Rc::new(RefCell::new(String::from("hello")));
func1(a.clone());
}
Run Code Online (Sandbox Code Playgroud)
这段代码仍然将错误(也许不是错误)留给运行时并陷入恐慌。那么我应该尽可能避免使用Rc
and吗?RefCell
这段代码算安全代码吗?
由于Rc
和RefCell
允许您编译在运行时可能会出现恐慌的代码,因此不要轻易使用它们。您可以使用try_borrow_mut
而不是borrow_mut
避免恐慌并自己处理结果。
话虽这么说,即使您防止了所有恐慌,Rc
并且RefCell
在运行时会产生成本,因为它们保留了引用计数器。在许多情况下,您可以通过以更生疏的方式重写代码来避免它们。
fn func1(mut string: String) -> String {
string = "func1".into();
func2(string)
}
fn func2(mut string: String) -> String {
string = "func2".into();
func3(string)
}
fn func3(string: String) -> String {
"func3".into()
}
fn main() {
let a = func1("hello".into());
}
Run Code Online (Sandbox Code Playgroud)
更简单,更安全。Rust 会为你进行优化。
要回答你的最后一个问题,使用borrow_mut
不被视为不安全代码,因为即使使用#![forbid(unsafe_code)]
指令代码也可以编译
归档时间: |
|
查看次数: |
1719 次 |
最近记录: |