Rust 析构函数

 

  • Trait std::ops::Drop

    如果你的自定义类型需要自己的析构函数,则只要实现std::ops::Drop trait 即可。例如:

     

struct HasDrop; //你的自定义类型。
​
impl Drop for HasDrop {
    fn drop(&mut self) { //std::ops::Drop trait 只有一个方法drop。
        println!("Dropping!"); //当你的自定义类型变量离开了`作用域`时, 析构函数drop被自动调用!
        //切记不允许手动直接调用。 
        //在此处释放各种资源。
    }
}
​
fn main() {
    let _x = HasDrop; 
    //如果你想提前析构释放变量,缩短变量作用域,可以手动直接调用`std::mem::drop`
    //drop(_x);
}
​

 


 

struct Droppable {
    name: &'static str,
}
​
//注意对于有子成员的自定义类型,如上面的结构体`Droppable` , 析构函数调用顺序为: 先整体后局部, 先父后子!
//即:Droppable::drop --> str::drop , 即依次调用每个子成员的析构函数。
​
// 为你的自定义类型实现std::ops::Drop trait 
impl Drop for Droppable {
    fn drop(&mut self) {
        println!("> Dropping {}", self.name);
        //此处释放各种资源
    }
}
​
fn main() {
    let _a = Droppable { name: "a" };
    
    //每一对儿花括号就是一个作用域!
    // block A
    {
        let _b = Droppable { name: "b" };
​
        // block B
        {
            let _c = Droppable { name: "c" };
            let _d = Droppable { name: "d" };
​
            println!("Exiting block B");
        }
        println!("Just exited block B");
​
        println!("Exiting block A");
    }
    println!("Just exited block A");
​
    // 调用`std::mem::drop`可以手动提前释放。
    drop(_a);
   
​
    println!("end of the main function");
​
    // `_a` 变量原本应该在离开最后一个花括号时,开始析构。
    // 但是因为前面已经提前手动调用`std::mem::drop`释放了变量, 所以此处不再重复析构。
}
​

【结构体及其子成员析构顺序验证例子】

#[derive(Debug)]
struct SubField(u8);
​
impl Drop for SubField {
    fn drop(&mut self) {
        println!("{:?}", self);
    }
}
​
#[derive(Debug)]
struct HasDrop
{
    a: SubField,
    b:SubField,
    c:SubField,
    d:SubField,
} //你的自定义类型。
​
impl Drop for HasDrop {
    fn drop(&mut self) { 
        println!("HasDrop!");
    }
}
​
fn main() {
    let _x = HasDrop{a:SubField(1), b:SubField(2), c:SubField(3), d:SubField(4)};
}
​
/*
* Program Output:
*HasDrop!
*SubField(1)
*SubField(2)
*SubField(3)
*SubField(4)
*/
//从程序输出确认析构顺序: 先父后子, 而每一个子成员析构顺序由其定义顺序决定。

 

  • 官方文档-析构顺序规定

The destructor of a type consists of

  1. Calling its std::ops::Drop::drop method, if it has one.

  2. Recursively running the destructor of all of its fields.

    • The fields of a struct, tuple or enum variant are dropped in declaration order. *

    • The elements of an array or owned slice are dropped from the first element to the last. *

    • The captured values of a closure are dropped in an unspecified order.

    • Trait objects run the destructor of the underlying type.

    • Other types don't result in any further drops.

* This order was stabilized in RFC 1857.

Variables are dropped in reverse order of declaration. Variables declared in the same pattern drop in an unspecified ordered.

详情请看:https://doc.rust-lang.org/reference/destructors.htmlhttps://github.com/rust-lang/rfcs/blob/master/text/1857-stabilize-drop-order.md

 

在C++中很有名的一种资源获取释放模式!主要利用类型的析构函数来及时地自动地清理释放持有的资源,避免资源泄露, 不啰嗦了, 详情请看:https://doc.rust-lang.org/rust-by-example/scope/raii.html

 

  • 一个析构函数编译报错的例子--所有权争夺

error: cannot move out of typeSqlTransaction<'a>, which defines theDroptrait [E0509]at line 12 col 22

struct SqlTransaction<'a> {
    connection: &'a Connection,
    transaction: Transaction<'a>,
}
​
impl<'a> Drop for SqlTransaction<'a> {
    fn drop(&mut self) {
        let result = self.transaction.commit(); //此行引发编译报错,因为commit(self)会转移走`transaction`所有权。
        //双方争夺`transaction`所有权, 可以将`transaction`包裹到Option中, 然后以Option::take让self放弃`transaction`的所有权; 或者替换掉commit(self),换成引用类的接口。详情请看:`https://stackoverflow.com/questions/34278607/can-not-move-out-of-type-which-defines-the-drop-trait-e0509`
        match result {
            Ok(_) => print!("herp"),
            Error => print!("lol"),
​
        }
    }
}

 

 

  • Author

作者:心尘了

email: 285779289@qq.com

git:https://github.com/yujinliang

水平有限,笔记草乱,难免谬误,海涵!

 

  • Reference

https://doc.rust-lang.org/rust-by-example/trait/drop.html

https://doc.rust-lang.org/std/ops/trait.Drop.html

https://doc.rust-lang.org/std/mem/fn.drop.html

https://stackoverflow.com/questions/34278607/can-not-move-out-of-type-which-defines-the-drop-trait-e0509

https://doc.rust-lang.org/nomicon/destructors.html

https://doc.rust-lang.org/reference/destructors.html

https://github.com/rust-lang/rfcs/blob/master/text/1857-stabilize-drop-order.md

https://doc.rust-lang.org/nomicon/constructors.html

https://doc.rust-lang.org/rust-by-example/scope/raii.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值