簡體   English   中英

Rust 函數沒有靜態生命周期?

[英]Rust function does not have static lifetime?

我正在嘗試編譯這個簡單的代碼:

fn dox(x: u8) -> u8 { x*2 }

fn main() {
    let cb: &'static (Fn(u8) -> u8) = &dox;
}

但它在 Rust 1.9 中失敗了:

x.rs:4:40: 4:43 error: borrowed value does not live long enough
x.rs:4     let cb: &'static (Fn(u8) -> u8) = &dox;
                                              ^~~
note: reference must be valid for the static lifetime...
x.rs:4:44: 5:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 4:43
x.rs:4     let cb: &'static (Fn(u8) -> u8) = &dox;
x.rs:5 }
error: aborting due to previous error

自由函數怎么可能沒有靜態生命周期? 這段代碼怎么會不安全?

&dox的類型不是&Fn(u8) -> u8 (甚至&fn(u8) -> u8 ),它只是強制轉換為&Fn(u8) -> u8 因此,您實際上是在獲取臨時地址。 臨時對象不會被提升為'static生命周期,即使它們原則上可以是'static 例如,此代碼也不起作用:

fn main() {
    let a: &'static i32 = &5;
}

有一些解決方法。 通常我們可以顯式地創建一個static變量並引用它:

fn main() {
    static FIVE: i32 = 5;
    let a: &'static i32 = &FIVE;
}

在您的特定情況下,它不能直接工作,因為Fn(u8) -> u8是一個未調整大小的類型(特別是特征),因此您不能將其放在static 你可以這樣做:

fn main() {
    static DOX: fn(u8) -> u8 = dox; // note: fn, not Fn
    let a: &'static Fn(u8) -> u8 = &DOX;
}

然而,對Fn* trait 對象的靜態引用是一件相當愚蠢的事情。 可以是'static引用'static閉包非常罕見,因此您不妨使用普通的fn(u8) -> u8類型並避開整個生命周期業務。

從 Rust 1.21 開始,“靜態提升”會自動執行,您的原始代碼會按原樣編譯。

此代碼也編譯:

fn main() {
    let a: &'static i32 = &5;
}

此外,不會從其環境中捕獲任何內容的閉包可以自動轉換為函數指針,因此您也不需要創建單獨的函數:

fn main() {
    let cb: fn(u8) -> u8 = |x| x * 2;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM