天天看點

2022-10-29:go語言中的defer能非常友善地處理資源釋放問題,rus

作者:福大大架構師每日一題

2022-10-29:go語言中的defer能非常友善地處理資源釋放問題,rust語言裡如何實作defer功能呢?

答案2022-10-29:

rust裡有時候你也必須用defer,别說是設計上的問題,因為這種情況你肯定會遇到。

有些時候第三方的結構體,析構函數是不滿足需求的,但你也不可能直接修改源碼。

第三方的結構體是無法直接實作Drop的,是以隻能另外定義結構體來包裹第三方的結構體,然後實作drop,這樣就能實作defer功能。這是裝飾器模式。

現在已經有現成的輪子,直接用就行。輪子有scopeguard和xjbutil。

scopeguard案例代碼如下:

extern crate scopeguard;
struct AA {
    a: i32,
    b: i32,
}


fn main() {
    println!("scopeguard");
    let mut a = AA { a: 1, b: 2 };
    println!("外部1----{:p}", &(a));
    println!("外部1----{:p}", &(a.a));
    println!("外部1----{}", a.a);


    let mut a = scopeguard::guard(&mut a, |a| {
        a.a = 13;
        println!("内部1----{:p}", &a);
        println!("内部1----{:p}", &a.a);
        println!("内部1----{}", a.a);
    });


    //let mut a = a;


    let mut a = scopeguard::guard(&mut a, |a| {
        a.a = 14;
        println!("内部2----{:p}", &a);
        println!("内部2----{:p}", &a.a);
        println!("内部2----{}", a.a);
    });


    //let mut a = a;
    a.a = 2;
    println!("外部2----{:p}", &a);
    println!("外部2----{:p}", &a.a);
    println!("外部2----{}", a.a);


    let mut a = scopeguard::guard(&mut a, |a| {
        a.a = 15;
        println!("内部3----{:p}", &a);
        println!("内部3----{:p}", &a.a);
        println!("内部3----{}", a.a);
    });


    //let mut a = a;


    println!("外部3----{:p}", &(a));
    println!("外部3----{:p}", &(a.a));
    println!("外部3----{}", a.a);
}           

xjbutil案例代碼如下:

use xjbutil::defer;
struct AA {
    a: i32,
    b: i32,
}


fn main() {
    println!("xjbutil");
    let mut a = AA { a: 1, b: 2 };
    println!("外部0----{:p}", &(a));
    println!("外部0----{:p}", &(a.a));
    println!("外部0----{}", a.a);


    let a = &mut a;
    println!("外部1----{:p}", &(a));
    println!("外部1----{:p}", &(a.a));
    println!("外部1----{}", a.a);


    defer!(
        |mut aa| {
            aa.a = 13;
            println!("内部1----{:p}", &aa);
            println!("内部1----{:p}", &aa.a);
            println!("内部1----{}", aa.a);
        },
        a
    );


    defer!(
        |mut a| {
            a.a = 14;
            println!("内部2----{:p}", &a);
            println!("内部2----{:p}", &a.a);
            println!("内部2----{}", a.a);
        },
        a
    );


    a.a = 2;
    println!("外部2----{:p}", &a);
    println!("外部2----{:p}", &a.a);
    println!("外部2----{}", a.a);


    defer!(
        |mut a| {
            a.a = 15;
            println!("内部3----{:p}", &a);
            println!("内部3----{:p}", &a.a);
            println!("内部3----{}", a.a);
        },
        a
    );


    println!("外部3----{:p}", &(a));
    println!("外部3----{:p}", &(a.a));
    println!("外部3----{}", a.a);
}           

結果如下:

2022-10-29:go語言中的defer能非常友善地處理資源釋放問題,rus
2022-10-29:go語言中的defer能非常友善地處理資源釋放問題,rus

繼續閱讀