繁体   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