为何结构体impl块中const的生命周期省略对切片无效?
Rust生命周期省略的特殊情况:impl块内嵌套引用常量编译失败问题
先看这段能正常编译的代码:
struct X; impl X { const ONE: &str = "one"; }
但为什么下面这段代码会编译失败?
struct X; impl X { const TWO: &[&str] = &["two"]; }
编译器报错信息如下:
error[E0491]: in type
&[&str], reference has a longer lifetime than the data it references
--> src/lib.rs:6:5
|
6 | const TWO: &[&str] = &["two"];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
有意思的是,如果把这个常量移到impl块外部定义,代码就能正常编译——按道理来说,定义位置不该影响生命周期推断才对。
问题原因:impl块内的生命周期省略规则差异
这本质是Rust生命周期省略规则在impl块内的特殊处理逻辑导致的:
- 对于单级引用类型(比如
&str):在impl块的常量中,编译器会自动将省略的生命周期推断为'static。第一个例子里,"one"是'static生命周期的字符串字面量,和推断出的&'static str完全匹配,所以编译通过。 - 对于嵌套引用类型(比如
&[&str]):在impl块内,编译器会先给外层的引用推断一个和当前impl绑定的隐式生命周期(即使结构体本身没有生命周期参数,这个规则依然会触发);而内层的&str还是会被推断为'static。这就导致外层引用的生命周期(绑定到impl的隐式生命周期)比内层的'static短,出现了"引用生命周期比它指向的数据长"的矛盾,因此编译报错。
而当把常量移到impl块外部时,编译器会将外层引用的生命周期也推断为'static,此时&'static [&'static str]和&["two"](字面量数组的引用是'static,内部字符串也是'static)完全匹配,自然能编译通过。
解决方法:显式指定'static生命周期
只需要给嵌套引用的所有层级都显式标注'static生命周期,就能让编译器按照预期处理:
struct X; impl X { const TWO: &'static [&'static str] = &["two"]; }
这样代码就能正常编译运行了。
内容的提问来源于stack exchange,提问作者user22608671
相关产品推荐
相关产品推荐

