在以下代码示例中:
fn default_values() -> &'static [u32] {
static VALUES: [u32; 3] = [1, 2, 3];
&VALUES
}
fn main() {
let values: [u32; 3] = [4, 5, 6];
let optional_values: Option<&[u32]> = Some(&values);
// this compiles and runs fine
let _v = optional_values.unwrap_or_else(|| default_values());
// this fails to compile
let _v = optional_values.unwrap_or_else(default_values);
}
Run Code Online (Sandbox Code Playgroud)
最后一个语句无法编译:
error[E0597]: `values` does not live long enough
--> src/main.rs:8:49
|
8 | let optional_values: Option<&[u32]> = Some(&values);
| ^^^^^^ borrowed value does not live long enough
...
12 | }
| - borrowed value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
Run Code Online (Sandbox Code Playgroud)
我在想:
unwrap_or_else(|| default_values())是正确的处理方式,或者是否有更好的模式这是因为default_values实现Fn() -> &'static [u32],但不是for<'a> Fn() -> &'a [u32].特征是不变的,所以你不能强迫"实现的东西Fn() -> &'static [u32]"到"实现的东西Fn() -> &'a [u32]"(对于一些'a小的东西'static),尽管从逻辑上讲,default_values它可以满足两者.
当它在闭包中调用时,default_values()返回a &'static [u32],但它可以立即强制转换为a &'a u32,使得闭包本身能够实现Fn() -> &'a [u32](&'a由编译器确定).
至于为什么添加as fn() -> &'static [u32]工作,我假设编译器可以识别函数指针类型fn() -> &'static [u32]能够实现Fn() -> &'a [u32]任何'a.我不确定为什么它也不能用于普通的功能和闭包; 或许未来的编译器版本可能足够智能以允许原始代码.
另一个解决方案是制作default_values一个可以实现所需Fn特性的类型:
fn default_values<'a>() -> &'a [u32] {
static VALUES: [u32; 3] = [1, 2, 3];
&VALUES
}
Run Code Online (Sandbox Code Playgroud)
'static这里的签名不是说"这是一个返回引用的函数",而是说"这是一个可以返回任何生命周期的引用的函数".我们知道"任何生命周期的参考"必须是一个'static参考,但编译器认为签名是不同的,因为这个签名具有额外的自由度.此更改足以使您的原始示例编译.
| 归档时间: |
|
| 查看次数: |
174 次 |
| 最近记录: |