繁体   English   中英

为什么对 const 进行静态引用会返回对临时变量的引用?

[英]Why does taking a static reference to a const return a reference to a temporary variable?

在 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
    }
}

Rust中的常量是编译时常量,而不是具有内存位置的实际变量。 Rust编译器可以替换使用它的常量的实际 如果您获取此类值的地址,则会获得临时地址。

Rust还具有静态变量的概念。 这些变量实际上具有与整个程序持续时间一致的存储器位置,并且对静态变量的引用确实导致具有'static寿命'static的引用。

也可以看看:

定义特征时,定义必须适用于所有可能的实现。

如果没有失败的例子,问题可能不会立即得到解决。 所以假设你有这样的类型:

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引用,所以函数可以返回它。 所有可能的实现都必须能够获得对Self 'static引用以实现特征,因此引用某些任意本地值不再存在问题。

这里的工作机制是静态提升。 RFC 1414

这是一个报价:

在函数体的块内:

  • 如果采用对 constexpr 右值的共享引用。 (&)
  • 而且 constexpr 不包含 UnsafeCell { ... } 构造函数。
  • 并且 constexpr 不包含返回包含 UnsafeCell 的类型的 const fn 调用。
  • 然后,不是将值转换为堆栈槽,而是将其转换为静态内存位置,并为结果引用提供“静态生命周期”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM