1 个不稳定版本
0.1.0 | 2022 年 8 月 20 日 |
---|
#738 在 内存管理
349 每月下载量
14KB
163 行
omniswap:一个用于在可能重叠的引用之间交换值的 Crate
动机示例
您不能简单地使用 std::mem::swap
在数组内部替换值
let mut a = [1, 2, 3];
// You cannot prove their disjointness!
std::mem::swap(&mut a[0], &mut a[2]);
您会得到以下消息
error[E0499]: cannot borrow `a[_]` as mutable more than once at a time
--> src/main.rs:4:31
|
4 | std::mem::swap(&mut a[0], &mut a[2]);
| -------------- --------- ^^^^^^^^^ second mutable borrow occurs here
| | |
| | first mutable borrow occurs here
| first borrow later used by call
|
= help: consider using `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
您可以使用专门的 <[T]>::swap
代替
let mut a = [1, 2, 3];
a.swap(0, 2);
那么二维数组呢?
let mut a = [[1, 2], [3, 4]];
// You cannot prove their disjointness!
std::mem::swap(&mut a[0][0], &mut a[1][1]);
这并不像第一个那么简单。
解决方案
此 Crate 通过提供基于哨兵的交换的泛型框架来解决此问题。
想法很简单:它留下一个假值以安全地移动值
let mut a = [[1, 2], [3, 4]];
let tmp = std::mem::replace(&mut a[0][0], 0);
let tmp = std::mem::replace(&mut a[1][1], tmp);
a[0][0] = tmp;
# assert_eq!(a, [[4, 2], [3, 1]]);
然而,在 Rust 中,最佳哨兵值因类型而异。
宏 swap!
会自动选择最佳哨兵并提供与 std::mem::swap
相同的接口
let mut a = [[1, 2], [3, 4]];
omniswap::swap!(&mut a[0][0], &mut a[1][1]);
# assert_eq!(a, [[4, 2], [3, 1]]);
用法
只需在想要使用 std::mem::swap
的地方使用 swap!
let mut x = 42;
let mut y = 84;
omniswap::swap!(&mut x, &mut y);
有关详细用法,请参阅 swap!
其他 API
此 Crate 提供以下变体
rotate!
-- 一次性交换多个值
此 Crate 还公开了 take!
和 Replace
。这些是在 swap!
和 rotate!
中使用的原始操作。