📅  最后修改于: 2021-01-08 14:01:13             🧑  作者: Mango
内部可变性模式是一种在我们具有不可变参考的情况下用于对参考进行变异的模式。 RefCell
要记住的要点:
根据借款规则,如果我们拥有不变的价值,那么我们就不能可变地借款。
让我们看一个简单的例子:
fn main()
{
let a = 15;
let b = &mut a;
}
输出:
在上面的示例中,我们看到不可变值不能可变地借用。但是,RefCell是实现内部可变性的一种方法。
RefCell
注意:两种类型的参考
一些要点:
借款()方法借用不可变的价值。可以同时进行多次不可变借用。
句法:
pub fn borrow(&self) -> Ref
让我们看一个发生多个不可变借位的简单示例:
use std::cell::RefCell;
fn main()
{
let a = RefCell::new(15);
let b = a.borrow();
let c = a.borrow();
println!("Value of b is : {}",b);
println!("Value of c is : {}",c);
}
输出:
让我们看一个紧急情况的简单例子:
use std::cell::RefCell;
fn main()
{
let a = RefCell::new(10);
let b = a.borrow();
let c = a.borrow_mut(); // cause panic.
println!("Value of b is : {}",b);
println!("Value of c is : {}",c);
}
输出:
在上面的示例中,程序在运行时由于不可变借项和可变借项而出现紧急情况,不能同时发生。
借款器_mut()方法借用可变值。可变借用只能发生一次。
句法:
pub fn borrow_mut(&self) -> RefMut;
让我们看一个简单的例子:
use std::cell::RefCell;
fn main()
{
let a = RefCell::new(15);
let b = a.borrow_mut();
println!("Now, value of b is {}",b);
}
让我们看一个紧急情况的简单例子:
use std::cell::RefCell;
fn main()
{
let a = RefCell::new(15);
let b = a.borrow_mut();
let c = a.borrow_mut();
}
输出:
在上面的示例中,可变借贷发生了两次。因此,程序在运行时出现紧急情况,并引发错误“已借用:BorrowMutError”。
我们可以结合使用Rc
让我们看一个简单的例子:
#[derive(Debug)]
enum List
{
Cons(Rc>,Rc),
Nil,
}
use List:: {Cons,Nil};
use std::rc::Rc;
use std::cell::RefCell;
fn main()
{
let val = Rc::new(RefCell::new(String::from("java")));
let a = Rc::new(Cons(Rc::clone(&val),Rc::new(Nil)));
let b = Cons(Rc::new(RefCell::new(String::from("C"))),Rc::clone(&a));
let c = Cons(Rc::new(RefCell::new(String::from("C++"))),Rc::clone(&a));
*val.borrow_mut() = String::from("C# language");
println!("value of a is : {:?}",a);
println!("value of b is : {:?}",b);
println!("value of c is : {:?}",c);
}
输出:
在上面的示例中,我们创建了一个变量“ val”,并将值“ java”存储到变量“ val”。然后,我们创建列表“ a”,并克隆“ val”变量,以便变量“ a”和“ val”都具有“ java”值的所有权,而不是将所有权从“ val”转移到“ a”变量。创建“ a”列表后,我们创建“ b”和“ c”列表并克隆“ a”列表。创建列表之后,通过使用rowe_mut()方法将“ val”变量的值替换为“ C#”语言”。