[英]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.