Rust编译错误E0515:无法返回临时值引用的解决方案求助
Rust编译错误E0515:返回临时值引用的修复方案
我尝试用静态值实例化结构体,但编译器提示创建了临时值,所有引用均为static,问题与rust-lang/rust#69574一致。以下是代码及编译错误信息,求修复或规避方法:
代码示例
struct OutputDescription { name: &'static str, } struct SubOutput<T> { sub_param_a: T, } struct Output { param_a: SubOutput<bool> } impl <T: Description>Description for SubOutput<T> { fn name() -> &'static str { "param_a" } fn fields() -> &'static [OutputDescription] { &[OutputDescription { name: T::name(), }] } } trait Description { fn name() -> &'static str; fn fields() -> &'static [OutputDescription]; }
编译错误信息
Compiling playground v0.0.1 (/playground) error[E0515]: cannot return reference to temporary value --> src/main.rs:19:9 | 19 | &[OutputDescription { | _________^- | |_________| | || 20 | || name: T::name(), 21 | || }] | || ^ | ||__________| | |__________returns a reference to data owned by the current function | temporary value created here For more information about this error, try `rustc --explain E0515`. error: could not compile `playground` (bin "playground") due to previous error
错误原因
直接返回&[OutputDescription { ... }]时,这个数组是函数栈上的临时值,生命周期仅存在于函数调用期间。函数返回后临时值会被销毁,因此编译器不允许返回其引用——哪怕数组内的字段都是&'static str,数组本身的生命周期也不满足'static要求。
修复方案
方案一:使用编译期静态常量数组
如果T::name()是编译期可确定的静态值,可以将数组定义为static常量,直接返回其引用:
struct OutputDescription { name: &'static str, } struct SubOutput<T> { sub_param_a: T, } struct Output { param_a: SubOutput<bool> } trait Description { fn name() -> &'static str; fn fields() -> &'static [OutputDescription]; } impl <T: Description>Description for SubOutput<T> { fn name() -> &'static str { "param_a" } fn fields() -> &'static [OutputDescription] { // 定义编译期静态数组 static FIELDS: [OutputDescription; 1] = [OutputDescription { name: T::name(), }]; &FIELDS } }
方案二:使用lazy_static延迟初始化
如果需要运行期动态生成数组(或T::name()非编译期常量),可以借助lazy_static crate实现线程安全的静态延迟初始化:
- 先在
Cargo.toml添加依赖:
[dependencies] lazy_static = "1.4.0"
- 修改代码:
use lazy_static::lazy_static; struct OutputDescription { name: &'static str, } struct SubOutput<T> { sub_param_a: T, } struct Output { param_a: SubOutput<bool> } trait Description { fn name() -> &'static str; fn fields() -> &'static [OutputDescription]; } impl <T: Description>Description for SubOutput<T> { fn name() -> &'static str { "param_a" } fn fields() -> &'static [OutputDescription] { lazy_static! { static ref FIELDS: Vec<OutputDescription> = vec![OutputDescription { name: T::name(), }]; } FIELDS.as_slice() } }
lazy_static会在第一次访问FIELDS时完成初始化,确保变量生命周期为'static,同时保证线程安全。
内容的提问来源于stack exchange,提问作者felix
相关产品推荐
相关产品推荐

