通過在Drop
實施中檢查std::thread::panicking
的返回值來實施中毒。如果它返回true
,則該值應該中毒。這裏有一個例子:
use std::cell::Cell;
use std::panic::{self, AssertUnwindSafe};
use std::thread;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum ResourceState {
Available,
Locked,
Poisoned,
}
struct Resource {
state: Cell<ResourceState>,
}
struct ResourceGuard<'a> {
resource: &'a Resource,
}
impl Resource {
fn new() -> Resource {
Resource {
state: Cell::new(ResourceState::Available),
}
}
fn lock(&self) -> ResourceGuard {
assert_eq!(self.state.get(), ResourceState::Available);
self.state.set(ResourceState::Locked);
ResourceGuard {
resource: self,
}
}
}
impl<'a> Drop for ResourceGuard<'a> {
fn drop(&mut self) {
self.resource.state.set(
if thread::panicking() {
ResourceState::Poisoned
} else {
ResourceState::Available
});
}
}
fn main() {
let resource = Resource::new();
println!("state: {:?}", resource.state.get()); // Available
{
println!("acquiring lock");
let _guard = resource.lock();
println!("state: {:?}", resource.state.get()); // Locked
println!("dropping lock");
}
println!("state: {:?}", resource.state.get()); // Available
let _ = panic::catch_unwind(AssertUnwindSafe(|| {
println!("acquiring lock");
let _guard = resource.lock();
println!("state: {:?}", resource.state.get()); // Locked
println!("panicking!");
panic!("panicking!");
}));
println!("state: {:?}", resource.state.get()); // Poisoned
}
嗯......生活和學習......我只是谷歌搜索「鏽型中毒」,發現這個:https://doc.rust-lang.org/std/sync/struct。 Mutex.html – NonCreature0714
這個問題並沒有說清楚你的意思是「用代碼演示類型中毒」。你是在尋找一箇中毒概念*的示範(毒化一個對象的意思,爲什麼有人會這樣做),中毒的一個特殊實現*(例如Rust互斥體中的一個),或者一個例子*使用*毒性類型?弗朗索瓦的回答顯示了Rust最小的完整實現概念。 – user4815162342
的確如此,他的回答確實顯示了MVCE的實施,但我希望在接受之前等待適當的時間。儘管讓某個人展示中毒概念以及爲什麼可以故意完成這將是非常有用的,但這不是我所要求的,所以我會澄清一下。 – NonCreature0714