在Rust中,我有以下代码:
pub trait Test: Sized {
const CONST: Self;
fn static_ref() -> &'static Self {
&Self::CONST
}
}
我的期望是,由于const
是'static
,所以我应该能够引用它也是'static
。但是,编译器给出以下错误:
error[E0515]: cannot return reference to temporary value
--> file.rs:9:9
|
9 | &Self::CONST
| ^-----------
| ||
| |temporary value created here
| returns a reference to data owned by the current function
这里如何引入临时变量?
此外,似乎在某些情况下引用常量确实有效。这是一个简短的具体示例,其Test的实现略有不同
pub trait Test: Sized {
fn static_ref() -> &'static Self;
}
struct X;
impl Test for X {
fn static_ref() -> &'static Self {
&X
}
}
答案 0 :(得分:7)
Rust中的常量是一个编译时常量,而不是带有内存位置的实际变量。 Rust编译器可以在任何使用常量的地方替换其实际的 value 。如果使用这样一个值的地址,那么您将获得一个临时地址。
Rust也具有静态变量的概念。这些变量实际上具有与整个程序持续时间一致的内存位置,并且引用静态变量的确会导致引用的生存期为'static
。
另请参阅:
答案 1 :(得分:3)
定义特征时,该定义必须对所有可能的实现有意义。
如果没有发生故障的示例,则可能无法立即解决问题。因此,假设您具有这样的类型:
struct MyStruct;
impl MyStruct {
const fn new() -> Self {
MyStruct
}
}
您试图实现以下特征:
impl Test for MyStruct {
const CONST: Self = MyStruct::new();
}
这将不起作用,因为static_ref
的实现现在看起来像这样:
fn static_ref() -> &'static Self {
// &Self::CONST
&MyStruct::new()
}
它正在函数内部创建一个值并尝试返回它。此值为不是静态的,因此'static
的生存期无效。
但是,只需稍微跳一下,您就可以使某些事情生效:
pub trait Test: Sized + 'static {
// This is now a reference instead of a value:
const CONST: &'static Self;
fn static_ref() -> &'static Self {
Self::CONST
}
}
struct MyStruct;
impl MyStruct {
const fn new() -> Self {
MyStruct
}
}
impl Test for MyStruct {
const CONST: &'static Self = &MyStruct::new();
}
之所以可行,是因为CONST
已经是'static
引用,因此该函数可以返回它。所有可能的实现都必须能够获得对'static
的{{1}}引用才能实现特征,因此,不再需要引用某些局部值。