1个不稳定版本
0.0.0 | 2022年12月17日 |
---|
#97 在 #drop
11KB
58 行
drop_cell
Rust中实现Drop
的另一种方式。
概述
此库提供了defer!
宏,用于将执行推迟到栈帧的末尾。
defer!
宏模拟Golang Defer语句。
defer!(println!("world"));
println!("hello");
return;
println!("unreachable");
输出
hello
world
借用规则
以下代码无法编译。
let mut v = vec![1, 2];
defer!(assert_eq!(v, &[1, 2, 3]));
// └─ immutable borrow occurs here ──────────┐
v.push(3); // │
// └─ mutable borrow occurs here │
// │
// immutable borrow will be used at the end of the stack frame ─┘
我们想在栈帧的末尾运行assert_eq!(v, &[1, 2, 3])
,但它违反了借用规则。
为了解决这个问题,我们需要将v
传递给defer!
。
let v = vec![1, 2];
// └─ consumes it ─┐
// ┌────────────┘
defer!(v => assert_eq!(v, &[1, 2, 3]));
v.push(3);
示例
use drop_cell::defer;
use std::io::Write;
use std::sync::mpsc;
fn main() {
no_arg();
args();
bind();
}
fn no_arg() {
let (tx, rx) = mpsc::channel();
defer! {
assert_eq!(rx.recv().unwrap(), "hello");
assert_eq!(rx.recv().unwrap(), "world");
};
tx.send("hello").unwrap();
tx.send("world").unwrap();
}
fn args() {
let (v1, v2) = (vec![], vec![]);
defer! { v1, v2 =>
assert_eq!(v1, b"hello");
assert_eq!(v2, b"world");
}
write!(v1, "hello").unwrap();
write!(v2, "world").unwrap();
}
fn bind() {
let ss = vec![];
defer! { v @ Some(ss) =>
let v = v.take().unwrap();
assert_eq!(v.as_slice(), ["hello", "world"]);
}
v.as_mut().unwrap().push("hello");
v.as_mut().unwrap().push("world");
}
何时使用以及何时不使用
何时使用
- 当你需要一个Finalizer但又不愿意为此创建一个
struct
时。