Efficient Ownership Transfer and Resource Release with `Option::take()`
Owner: SnippetBot
Created: 2026-08-08 00:00:26
Size: 1.87 KB
Expires: Never
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
struct MyResource {
id: u32,
data: String,
}
impl Drop for MyResource {
fn drop(&mut self) {
println!("Dropping MyResource with ID: {}", self.id);
}
}
struct ResourceContainer {
resource: Option<MyResource>,
}
impl ResourceContainer {
fn new(id: u32, data: &str) -> Self {
ResourceContainer {
resource: Some(MyResource { id, data: data.to_string() }),
}
}
// Safely takes ownership of the resource, leaving `None` in its place.
// This prevents double-frees or use-after-move scenarios.
fn take_resource(&mut self) -> Option<MyResource> {
self.resource.take()
}
// Shows current state without moving the resource
fn inspect_resource(&self) {
match &self.resource {
Some(r) => println!("Container holds resource ID: {}", r.id),
None => println!("Container holds no resource."),
}
}
}
fn main() {
let mut container = ResourceContainer::new(1, "Initial data");
container.inspect_resource();
// Take the resource from the container
if let Some(resource_taken) = container.take_resource() {
println!("Successfully took resource with ID: {}", resource_taken.id);
// resource_taken is now owned here, and will be dropped when it goes out of scope.
// container.resource is now None.
} else {
println!("Failed to take resource.");
}
container.inspect_resource();
// Attempting to take again will yield None
if let Some(resource_taken_again) = container.take_resource() {
println!("This should not happen: took resource again with ID: {}", resource_taken_again.id);
} else {
println!("Cannot take resource again, it's already gone.");
}
// When `container` goes out of scope, it will drop its `resource` field,
// which is currently `None`, so no double-drop occurs.
}