Box与解引用

2021-09-03  本文已影响0人  简书网abc

1. 智能指针是box

//1、最简单最直接的智能指针是box,其类型为Box<T>。box允许将值放在堆上而不是栈上,
// 留着栈上的则是指向堆数据的指针。
// 除了数据被存储在堆上外,box没有任何性能损失。
//
//2、box适合用于如下场景: (单一所有权, 非线程安全,编译期检查)
//(1)当有一个在编译时未知大小的类型,而又需要再确切大小的上下文中使用这个类型值的时候;
// (举例子:在一个list环境下,存放数据,但是每个元素的大小在编译时又不确定)
//(2)当有大量数据并希望在确保数据不被拷贝的情况下转移所有权的时候;
//(3)当希望拥有一个值并只关心它的类型是否实现了特定trait而不是其具体类型时。
fn main() {
    let b = Box::new(5); //b存储于栈上,5存储在堆上,b指向5所在的内存
    println!("b = {}", b);
    println!("Hello, world!");
}

2. 实现Deref trait

use std::ops::Deref;

struct MyBox<T>(T);
impl <T> MyBox<T> {
    fn new(x: T) -> MyBox<T> {
        MyBox(x)
    }
}
// 自定义结构体需要实现该 Deref trait, 才能被解引用.
impl <T> Deref for MyBox<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}

fn main() {
    let x = 5;
    let y = MyBox::new(x);

    assert_eq!(5, x);
    assert_eq!(5, *y);   // 解引用
}

3. 使用 Drop Trait 运行清理代码

引用文档: 
https://rust.bootcss.com/ch15-03-drop.html
//1、Drop trait类似于其它语言中的析构函数,当值离开作用域的时候执行此函数的代码。

struct Dog {
    name: String,
}
impl Drop for Dog {
    fn drop(&mut self) {
        println!("dog {} leave.", self.name);
    }
}

fn main() {
    let a = Dog{name: String::from("wangcai")};
    {
        let b = Dog{name: String::from("dahuang")};
        println!("0++++++++++++++++++++");
    }   // 在此会调用析构函数

    drop(a);  //这里手工调用析构函数
    println!("1++++++++++++++++++");
}

//结果:
// 0++++++++++++++++++++
// dog dahuang leave.
// dog wangcai leave.
// 1++++++++++++++++++
上一篇 下一篇

猜你喜欢

热点阅读