最简单的解决方案可能是使用
ManuallyDrop
并且简单地从不降低值。
struct CustomHistogramTimer(ManuallyDrop<HistogramTimer>);
然后你可以删除你的
Drop
实施删除此类型时,包含
HistogramTimer
将被遗忘(丢弃而不丢弃)。
但是,请注意
直方图计时器
包含
Histogram
,依次包含
Arc
到直方图的内部状态。
这意味着不丢弃
直方图计时器
将导致直方图的状态永远不会被释放,因为
弧
的引用计数永远不会变为零。
然而,似乎有一个解决方案。的文档
HistogramTimer::stop_and_discard
说(强调我的):
观察并返回计时器持续时间(秒)。
它返回自计时器启动以来经过的浮点秒数,
而不记录到任何直方图。
好的,很好,但这是一种消耗性的方法。我们不能在
&mut HistogramTimer
,这是我们在drop代码中所能得到的全部内容。
值得庆幸的是,这与
手动下降
方法事实上,这种特殊情况是的主要用途之一
手动下降
。我们必须使用不安全的代码来调用
ManuallyDrop::take
,这给了我们内在的所有权
T
。只要我们从不使用
手动下降
再说一遍,由于我们将在drop代码中执行此操作,因此很容易确保。
impl Drop for CustomHistogramTimer {
fn drop(&mut self) {
// SAFETY: The ManuallyDrop is being dropped and won't be used again.
let timer = unsafe { ManuallyDrop::take(&mut self.0) };
timer.stop_and_discard();
}
}
如果您喜欢不使用不安全代码的方法,可以使用
Option
。虽然我们可以很容易地证明代码永远不会死机,但编译器不能,因此任何使用内部
直方图计时器
将有一个
None
检查已发出。
struct CustomHistogramTimer(Option<HistogramTimer>);
impl Drop for CustomHistogramTimer {
fn drop(&mut self) {
self.0.take().unwrap().stop_and_discard();
}
}
impl CustomHistogramTimer {
pub fn stop_and_record(self) -> f64 {
self.0.unwrap().stop_and_record()
}
pub fn stop_and_discard(self) -> f64 {
self.0.unwrap().stop_and_discard()
}
}