1 个不稳定版本
| 0.1.7 | 2020年8月14日 |
|---|---|
| 0.1.6 |
|
| 0.1.5 |
|
| 0.1.4 |
|
| 0.1.2 |
|
#74 在 Rust 模式 中
83,076 每月下载量
在 164 个 包中使用 (37 个直接使用)
27KB
187 行
replace_with
暂时获取可变位置上的值的所有权,并根据旧值替换为新值。
此包提供了函数 replace_with(),类似于 std::mem::replace(),但它允许替换值从原始值映射。
有关其优点的讨论,请参阅 RFC 1736。它从未合并,并且所需的从 &mut T 暂时移动的能力尚不存在,因此此包是我的临时解决方案。
这与take_mut非常相似,不过使用了Drop而不是std::panic::catch_unwind()来响应堆栈展开,从而避免了调用extern "C" __rust_maybe_catch_panic()带来的优化屏障。因此,它比之前的实现快∞倍。API还尝试使在panic情况下的行为更加明确——replace_with()接受两个闭包,从而避免了在“标准情况”下(映射闭包FnOnce(T) -> T会panic,就像take_mut::take()一样)终止。然而,如果第二个闭包FnOnce() -> Tpanic,则确实会终止。使用replace_with_or_abort()可以获取“第一次panic时终止”的行为。
示例
考虑这个激励示例
enum States {
A(String),
B(String),
}
impl States {
fn poll(&mut self) {
// error[E0507]: cannot move out of borrowed content
*self = match *self {
// ^^^^^ cannot move out of borrowed content
States::A(a) => States::B(a),
States::B(a) => States::A(a),
};
}
}
根据上下文,这可能相当难以解决。然而,使用这个crate
enum States {
A(String),
B(String),
}
impl States {
fn poll(&mut self) {
replace_with_or_abort(self, |self_| match self_ {
States::A(a) => States::B(a),
States::B(a) => States::A(a),
});
}
}
太棒了!
no_std
要使用replace_with与no_std,您必须通过指定依赖关系来禁用默认启用的std功能,如下所示
# Cargo.toml
[dependencies.replace_with]
version = ...
default-features = false
features = []
...
replace_with()和replace_with_or_default()函数在稳定版Rust中,无论是否使用std都可用。
然而,默认情况下,replace_with_or_abort()函数使用std::process::abort(),这在no_std中不可用。
因此,默认情况下,replace_with会调用core::intrinsics::abort(),这反过来又需要nightly Rust。
对于稳定的no_std来说,并非所有事情都失去了,replace_with还有一招
panic = "abort"
如果你在 crate 的 Cargo.toml 文件的 [profile] 部分中定义了 panic = abort ...
# Cargo.toml
[profile.debug]
panic = "abort"
[profile.release]
panic = "abort"
… 并在你的 crate 的 Cargo.toml 文件的 dependencies 部分添加了 "panic_abort" 功能到 replace_with ...
# Cargo.toml
[dependencies.replace_with]
features = ["panic_abort"]
...
… 那么 "panic_abort" 功能将启用 replace_with_or_abort_unchecked() 函数,它在稳定版 Rust 中作为一个 unsafe 函数,简单地包装了 ptr::write(dest, f(ptr::read(dest)));.
注意:只有在你定义了 panic = "abort" 的情况下才能使用此函数,否则可能会发生不良后果。你必须 确保 维护此不变性!
许可协议
许可协议为以下之一:
- Apache License, Version 2.0, (LICENSE-APACHE.txt 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT.txt 或 https://open-source.org.cn/licenses/MIT)
由你选择。
除非你明确表示,否则根据 Apache-2.0 许可证定义,你提交的任何有意包含在作品中的贡献都将根据上述协议双重许可,不附加任何其他条款或条件。