5 个稳定版本
使用旧的 Rust 2015
1.0.4 | 2018 年 9 月 17 日 |
---|---|
1.0.3 | 2018 年 2 月 25 日 |
在 内存管理 中排名第 235
每月下载量 102,913
用于 635 个 Crates(直接使用 11 个)
14KB
131 行
允许故意泄漏内存的 Discard 特性。
有关详细信息,请参阅文档。
lib.rs
:
在某些情况下,您可能需要故意泄漏一些内存,而不是其他内存。这个 crate 可以帮到您!
但在解释之前,您可能想知道:为什么我想要泄漏内存呢?
在某些罕见的情况下,泄漏内存可能是所希望的或必要的。
例如,假设我正在使用 stdweb,它允许我在 Rust 中使用 JavaScript API。
所以我写了一些这样的代码
node.add_event_listener(|event: ClickEvent| {
// ...
});
看起来合理,对吧?但是有一个问题:`add_event_listener` 方法返回一个 `EventListenerHandle`,当 `EventListenerHandle` 被丢弃时,它将删除事件监听器。
因为我没有使用 `EventListenerHandle`,所以它立即被丢弃,因此它接收不到任何事件!
好吧,没问题,只需使用 std::mem::forget
// This will automatically remove the event listener when `handle` is dropped
let handle = node.add_event_listener(|event: ClickEvent| {
// ...
});
// Now it will no longer remove the event listener
std::mem::forget(handle);
现在事件监听器将永远保持活动状态,这正是我想要的。
但是这里有两个问题
-
我想要它永远保持事件监听器活动,但我还想清理任何未使用的内部内存。使用
std::mem::forget
会造成它泄漏所有内存,这是浪费的。 -
在有些情况下,我想要泄漏事件监听器,然后稍后取消泄漏。使用
std::mem::forget
是不可能的。
所有这些问题的解决方案是
-
`EventListenerHandle` 不应该实现
Drop
特性。 -
EventListenerHandle
应该实现Discard
接口。 -
add_event_listener
方法应该返回DiscardOnDrop<EventListenerHandle>
。
现在让我们看看可能的情况
// This will automatically remove the event listener when `handle` is dropped
let handle = node.add_event_listener(|event: ClickEvent| {
// ...
});
// Now it will no longer remove the event listener, this is similar to `std::mem::forget`
let leaked = DiscardOnDrop::leak(handle);
// Now it will remove the event listener, even though it was leaked
leaked.discard();
DiscardOnDrop::leak
和 std::mem::forget
之间有两个巨大的区别
-
std::mem::forget
泄露了所有内存,而DiscardOnDrop::leak
只泄露了最少的内存:未使用的内存被正确清理。 -
使用
std::mem::forget
,在值泄露后无法清理它,但使用DiscardOnDrop::leak
,您可以在值泄露后手动丢弃它。
大多数时候您不需要担心这些:当它被丢弃时,DiscardOnDrop
会自动调用 discard
,所以在那种情况下 Discard
的行为与 Drop
相同。
所以您可以正常使用 Rust 习惯用法,一切都会如您所期望的那样工作。您只需在需要故意泄露一些内存时担心 Discard
。