1 个不稳定版本
0.1.0 | 2024年3月2日 |
---|
#284 in 内存管理
47KB
863 行
RcOCell
为Rc<RefCell<Option<T>>>
及其弱变体提供包装。
包含在此类数据结构上通常执行的各种实用程序。
简单示例
pub fn main() {
let cell : RcOCell<u8> = RcOCell::from_value(1u8);
//The usual RefCell stuff...
let borrowed : Ref<u8> = cell.borrow();
//...
drop(borrowed);
let borrowed_mut : RefMut<u8> = cell.borrow_mut();
//...
drop(borrowed_mut);
}
信息
以下函数作为RcoCell和WeakRcoCell的一部分提供
一般来说,所有以"try"开头的前缀函数都不会panic。所有没有此前缀的函数可能会panic,具体取决于它们所做的工作。
借用
borrow
和borrow_mut
- 就像
RefCell
一样
- 就像
try_borrow
和try_borrow_mut
- 就像
RefCell
一样,但错误类型是一个枚举。
- 就像
这些调用要么panic,要么在单元格为空时失败。正常的Rust借用规则适用:只有1个可变借用或n个普通借用。如果在运行时违反借用规则,则要么panic,要么失败。
修改
set
和try_set
- 设置值并返回一个Option作为前一个值
- 如果值被借用,则不起作用。
replace
和try_replace
- 设置值,直接返回前一个值。
- 在空单元格上不起作用。
- 如果值被借用,则不起作用。
clear
和try_clear
- 清除值并返回一个Option作为前一个值
- 如果值被借用,则不起作用。
get_and_clear
和try_get_and_clear
- 清除值并直接返回前一个值。
- 如果值被借用,则不起作用。
- 在空单元格上不起作用。
compute
和try_compute
- 调用一个Fn以条件性地计算一个新值作为替换。
- 如果值被借用,则不起作用。
compute_if_present
和try_compute_if_present
- 调用一个Fn以条件性地计算一个新值作为替换。
- 如果值被借用,则不起作用。
- 在空单元格上什么也不做。
compute_if_absent
- 调用一个Fn来计算一个新值。
- 在空单元格或具有借用值的单元格上什么也不做。
swap
和try_swap
- 就像
RefCell::swap
一样 - 将在两个单元格之间交换值。
- 就像
访问
get_and_clone
和try_get_and_clone
- 直接返回单元格当前值的副本。
- 如果值是可变借用,则不会工作。
- 在空单元格上不起作用。
- 仅在实现 Clone 特性的类型上可用。
if_present_mut
、if_present
、try_if_present
和try_if_present_mut
- 如果单元格不为空,则通过值引用调用 Fn。
- 空单元格上不执行任何操作。
- 如果值被借用,则 mut 变体将不会工作。
- 如果值被可变借用,则正常变体将不会工作。
map
、map_mut
、try_map
、try_map_mut
- 通过值引用调用 Fn 以执行类型转换。
- Fn 的签名是
Fn(&T) -> X
或Fn(&mut T) -> X
- X 是转换的结果类型。
- T 是单元格中的类型。
- 整个方法签名是
Option<X>
或Result<Option<X>, RcOCellError>
- 在空单元格上不起作用。
- 如果值被借用,则 mut 变体将不会工作。
- 如果值被可变借用,则正常变体将不会工作。
转换
T
可以通过into
转换为RcOCell<T>
RcOCell<Vec<T>>
可以通过try_into
转换为Vec<T>
RcOCell<T>
可以通过into
转换为Rc<RefCell<Option<T>>>
Rc<RefCell<Option<T>>>
可以通过into
转换为RcOCell<T>
RcOCell<T>
可以通过into
转换为WeakRcOCell<T>
- 还有一个专门的
downgrade
方法,就像Rc::downgrade
。
- 还有一个专门的
WeakRcOCell<T>
可以通过try_into
转换为RcOCell<T>
- 还有一个专门的
upgrade
方法,就像Rc::upgrade
。
- 还有一个专门的
RcOCell<T>
可以通过try_into
转换为Option<T>
RcOCell<T>
可以通过into
转换为Result<Option<T>, RcOCellError>
- 普通
RefCell
借用方法的'error'类型可以通过into
或?
运算符转换为RcOCellError
构造函数
from_value
和from
- 创建一个带有值的新的cell,其中一个来自
From<T>
特质
- 创建一个带有值的新的cell,其中一个来自
from_option
- 接收一个Option作为参数,并创建一个带有或没有值的cell。
new
- 创建一个空cell。
杂项
downgrade
和upgrade
- 弱引用和普通引用cell之间的转换
clone
- 就像
Rc::clone
一样增加引用计数。
- 就像
更大的例子
pub fn main() {
let cell : RcOCell<u8> = RcOCell::from_value(1u8); //RcOCell::new() creates a empty cell.
//Remove the value from the cell
let old_value : Option<u8> = cell.clear(); //old value would be 1u8.
let borrow_result : Result<u8, RcOCellError> = cell.try_borrow();
if borrow_result.is_err() {
//Would be error because cell is empty.
//If you want to handle the RcOCellError error, it's an enum.
//Can be handled like this:
match borrow_result.unwrap_err() {
RcOCellError::NoValue => {println!("No value present")},
RcOCellError::BorrowError(_) => {}, //Won't happen in this case
RcOCellError::Dropped => {}, //Won't happen in this case
}
}
//Now cell has value 2. old_value is None.
let old_value : u8 = cell.set(2u8);
let borrowed : Ref<u8> = cell.borrow();
//set would panic, because the value is still borrowed, try_set will fail with RcOCellError::BorrowError
let try_set_result : Result<u8, RcOCellError> = cell.try_set(4u8);
drop(borrowed);
//Now it will work!
let try_set_result : Result<u8, RcOCellError> = cell.try_set(4u8);
//2u8 is the old value, 4u8 is now in the cell
let old_value : u8 = try_set_result.unwrap();
let current_value : u8 = cell.get_and_clone(); //Only works for all T that implement Clone trait, in this case 4u8
let current_value : u8 = cell.get_and_clear(); //Cell is empty again after this call. current_value 4u8
//Another call to get_and_clear would panic as cell is empty.
let get_result : Result<u8, RcOCellError> = cell.try_get_and_clear();
//Result is once again RcOCellError::NoValue Error
}