#swap #reference

no-std omniswap

在可能重叠的引用之间交换值

1 个不稳定版本

0.1.0 2022 年 8 月 20 日

#738内存管理

Download history 63/week @ 2024-03-11 107/week @ 2024-03-18 116/week @ 2024-03-25 147/week @ 2024-04-01 175/week @ 2024-04-08 111/week @ 2024-04-15 92/week @ 2024-04-22 127/week @ 2024-04-29 110/week @ 2024-05-06 96/week @ 2024-05-13 101/week @ 2024-05-20 85/week @ 2024-05-27 105/week @ 2024-06-03 50/week @ 2024-06-10 89/week @ 2024-06-17 92/week @ 2024-06-24

349 每月下载量

MIT/Apache

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! 中使用的原始操作。

无运行时依赖