RAII

Rust 中的变量不仅仅在栈中保存数据:它们还拥有资源,例如 Box<T> 拥有堆中的内存。Rust 强制执行 RAII(资源获取即初始化),因此每当对象超出作用域时,都会调用其析构函数并释放其拥有的资源。

这种行为可以防止资源泄漏错误,因此您永远不必手动释放内存或担心内存泄漏!以下是一个快速展示

// raii.rs
fn create_box() {
    // Allocate an integer on the heap
    let _box1 = Box::new(3i32);

    // `_box1` is destroyed here, and memory gets freed
}

fn main() {
    // Allocate an integer on the heap
    let _box2 = Box::new(5i32);

    // A nested scope:
    {
        // Allocate an integer on the heap
        let _box3 = Box::new(4i32);

        // `_box3` is destroyed here, and memory gets freed
    }

    // Creating lots of boxes just for fun
    // There's no need to manually free memory!
    for _ in 0u32..1_000 {
        create_box();
    }

    // `_box2` is destroyed here, and memory gets freed
}

当然,我们可以使用 valgrind 来仔细检查内存错误

$ rustc raii.rs && valgrind ./raii
==26873== Memcheck, a memory error detector
==26873== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==26873== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==26873== Command: ./raii
==26873==
==26873==
==26873== HEAP SUMMARY:
==26873==     in use at exit: 0 bytes in 0 blocks
==26873==   total heap usage: 1,013 allocs, 1,013 frees, 8,696 bytes allocated
==26873==
==26873== All heap blocks were freed -- no leaks are possible
==26873==
==26873== For counts of detected and suppressed errors, rerun with: -v
==26873== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

这里没有泄漏!

析构函数

Rust 中的析构函数概念是通过 Drop 特征提供的。当资源超出作用域时,将调用析构函数。并非所有类型都需要实现此特征,仅当您的类型需要自己的析构函数逻辑时才实现它。

运行下面的例子,看看 Drop trait 是如何工作的。当 main 函数中的变量超出作用域时,自定义析构函数将被调用。

struct ToDrop;

impl Drop for ToDrop {
    fn drop(&mut self) {
        println!("ToDrop is being dropped");
    }
}

fn main() {
    let x = ToDrop;
    println!("Made a ToDrop!");
}

另请参阅

Box