std::mem::forget 函数
为什么在转换为迭代器后,不会调用 drop 函数
- 因为在 into_iter 中使用了
std::mem::forget
函数
into_iter
函数将一个集合转换为一个迭代器,它会获取集合的所有权。
- 创建一个迭代器对象。
- 将集合的所有权转移到迭代器中。
- 防止集合的析构函数被自动调用(因为集合的所有权已经被转移)。
std::mem::forget
是 Rust 标准库中的一个函数,它的作用是防止 Rust 自动调用析构函数。具体来说:
- 当你调用
forget(self)
时,self 的所有权被“遗忘”,Rust 不会自动调用其析构函数。 - 这通常用于手动管理资源的生命周期,例如在实现自定义迭代器时。
函数原型
pub fn forget<T>(t: T)
使用场景,主要有三种:手动管理资源、与FFI进行交互、自定义迭代器
- 手动管理资源
use std::mem::forget;
use std::ptr;
struct MyResource {
data: *mut u8,
}
impl Drop for MyResource {
fn drop(&mut self) {
println!("Dropping MyResource");
unsafe { ptr::drop_in_place(self.data); }
}
}
fn main() {
let resource = MyResource { data: Box::into_raw(Box::new(42)) };
// 遗忘 resource,防止自动调用 Drop
forget(resource);
// 手动释放资源
unsafe {
println!("Manually dropping resource");
Box::from_raw(resource.data); // 调用 Box 的析构函数
}
}
- 与 FFI 交互:将资源传递给C代码时,防止 Rust 在外部的C代码仍然使用这些资源时自动释放它们。 ```rust use std::mem::forget;
struct MyResource { data: *mut u8, } impl Drop for MyResource { fn drop(&mut self) { println!(“Dropping MyResource”); // 释放资源 } } fn pass_to_c(resource: MyResource) { // 将资源传递给 C 代码 unsafe { // 假设有一个 C 函数接收资源 // c_function(resource.data); } // 遗忘资源,防止自动调用 Drop forget(resource); } fn main() { let resource = MyResource { data: Box::into_raw(Box::new(42)) }; pass_to_c(resource); }
- **自定义迭代器**
```rust
use std::mem::forget;
struct MyCollection {
data: Vec<i32>,
}
impl Drop for MyCollection {
fn drop(&mut self) {
println!("Dropping MyCollection");
}
}
struct MyIterator {
data: Vec<i32>,
index: usize,
}
impl MyCollection {
fn into_iter(self) -> MyIterator {
let iter = MyIterator {
data: self.data,
index: 0,
};
// 遗忘原始集合,防止自动调用 Drop
forget(self);
iter
}
}
fn main() {
let collection = MyCollection { data: vec![1, 2, 3] };
let iter = collection.into_iter();
for item in iter {
println!("{}", item);
}
}
forget 的主要作用是防止 Drop 函数被自动调用,用于需要手动管理资源的生命周期场景。