ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Rust 特性: Drop 特性(类 C++ 析构函数)

2021-11-14 16:31:37  阅读:180  来源: 互联网

标签:free Drop point drop bytes C++ Point 特性 release


Rust 特性: Drop 特性(类 C++ 析构函数)

文章目录

正文

0. 关于析构函数

写过 C++ 的应该都知道,资源被释放的时候会调用析构函数,方法签名如下

class AClass {
    public:
        ~AClass();
}

Java 也有类似的函数

class Object {
    finialize();
}

但是由于 Java 引入了 GC 的概念,因此真实的资源回收时机变得模糊,可以说是一个挺失败的设计hh

当然,作为与 C 语言同层级的现代语言,Rust 也提供了相应的析构函数写法,以一个特殊的 Trait - Drop 的形式提供,实现方式如下

impl Drop for AStruct {
    fn drop(&mut self) {
        // do something before drop
    }
}

1. 代码实现

下面我们来看看代码实现,先定义两个结构体,又是熟悉的 Point 和 Rectangle

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

#[derive(Debug)]
struct Rectangle {
    top_left: Point,
    bottom_right: Point,
}

1.0 Drop 实现

然后为这两个结构体实现一个一样的 Drop 特性

use std::fmt::Debug;
use std::mem::size_of_val;

fn drop_resource<T: Debug>(item: &mut T) {
    println!("=== [release resources] {:?} ,free: {} bytes", item, size_of_val(item));
}

impl Drop for Point {
    fn drop(&mut self) {
        drop_resource(self);
    }
}

impl Drop for Rectangle {
    fn drop(&mut self) {
        drop_resource(self);
    }
}

1.1 自动回收

第一个例子我们先看自动回收的效果

  • Sample1:两个 Point
fn main() {
    let point = Point { x: -1, y: -1 };
    println!("point = {:?}", point);

    let point = Point { x: 0, y: 0 };
    println!("point = {:?}", point);
}
point = Point { x: -1, y: -1 }
point = Point { x: 0, y: 0 }
=== [release resources] Point { x: 0, y: 0 } ,free: 8 bytes
=== [release resources] Point { x: -1, y: -1 } ,free: 8 bytes

我们可以看到即便修改 point 指向,实际上 -1 的那个 Point 依旧会存活整个作用域的生命周期;同时注意到释放看起来应该是照着方法栈的顺序一一回收,不过直觉告诉我们这个顺序不可依赖

  • Sample2:Rectangle 与 Box
fn main() {
    let rect = Rectangle {
        top_left: Point { x: 1, y: 1 },
        bottom_right: Point { x: 2, y: 2 },
    };
    println!("rect = {:?}", rect);

    let box_rect = Box::new(Rectangle {
        top_left: Point { x: 3, y: 3 },
        bottom_right: Point { x: 4, y: 4 },
    });
    println!("box_rect = {:?}", box_rect);
}
rect = Rectangle { top_left: Point { x: 1, y: 1 }, bottom_right: Point { x: 2, y: 2 } }
box_rect = Rectangle { top_left: Point { x: 3, y: 3 }, bottom_right: Point { x: 4, y: 4 } }
=== [release resources] Rectangle { top_left: Point { x: 3, y: 3 }, bottom_right: Point { x: 4, y: 4 } } ,free: 16 bytes
=== [release resources] Point { x: 3, y: 3 } ,free: 8 bytes
=== [release resources] Point { x: 4, y: 4 } ,free: 8 bytes
=== [release resources] Rectangle { top_left: Point { x: 1, y: 1 }, bottom_right: Point { x: 2, y: 2 } } ,free: 16 bytes
=== [release resources] Point { x: 1, y: 1 } ,free: 8 bytes
=== [release resources] Point { x: 2, y: 2 } ,free: 8 bytes

我们发现作为 Rectangle 子元素的 Point 也会递归释放,一样顺序不可依赖(如果编译器对栈上变量做重排列会打乱顺序)

1.2 主动回收

实际上我们依赖自动回收已经很够了,同时 Rust 的资源利用跟踪机制实在是非常的好,所以我们会用到主动回收的时机是在少之又少,也是一个全局提供的 drop 函数

fn main() {
    let point = Point { x: -1, y: -1 };
    println!("point = {:?}", point);
    drop(point);

    let point = Point { x: 0, y: 0 };
    println!("point = {:?}", point);
}
point = Point { x: -1, y: -1 }
=== [release resources] Point { x: -1, y: -1 } ,free: 8 bytes
point = Point { x: 0, y: 0 }
=== [release resources] Point { x: 0, y: 0 } ,free: 8 bytes

都主动回收了,当然 drop 特性也就提前执行咯

其他资源

参考连接

TitleLink
Drop - Rust by Examplehttps://doc.rust-lang.org/rust-by-example/trait/drop.html

完整代码示例

https://github.com/superfreeeee/Blog-code/tree/main/back_end/rust/rust_drop

标签:free,Drop,point,drop,bytes,C++,Point,特性,release
来源: https://blog.csdn.net/weixin_44691608/article/details/121319407

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有