【问题标题】:Reassignment of static items inside of a function body重新分配函数体内的静态项
【发布时间】:2021-10-14 06:16:24
【问题描述】:

假设我们有以下代码:

fn main() {
    for _ in 0..10 {
        let _ = get_static_ref();
    }
}

struct SomeStruct {
    value: usize
}

fn get_static_ref() -> &'static SomeStruct {
    static MY_STRUCT: SomeStruct = SomeStruct { value: 1 };
    &MY_STRUCT
}

MY_STRUCT 是否会在每次 get_static_ref 调用时重新分配,还是编译器只是从函数体中删除此分配? 因为如果它被重新分配,那么它有点违反规则,非 mut 静态项是不可变的,因此这些重新分配不应该发生,但这只是我的猜测。

我无法在 Rust 文档中找到对这种情况的明确解释。

【问题讨论】:

  • 不分配一次,您可以通过此代码测试行为:play.rust-lang.org/…
  • 一种思考方式是get_static_ref() 中的= 标记不表示assignment,而是initialization。由于MY_STRUCT是静态的,所以初始化只执行一次。
  • 哦,如果你这样想,现在就有意义了,谢谢:)

标签: rust static


【解决方案1】:

如果您查看generated code,您将看到MyStruct 仅创建一次(在编译时),并且该函数仅返回现有实例:

example::get_static_ref:
        lea     rax, [rip + example::get_static_ref::MY_STRUCT]
        ret

example::get_static_ref::MY_STRUCT:
        .asciz  "\001\000\000\000\000\000\000"

【讨论】:

    【解决方案2】:

    the Rust reference 的以下摘录可以解释静态 MY_STRUCT 将在编译时评估一次。

    • 静态初始值设定项是在编译时求值的常量表达式。
    • 静态项类似于常量,不同之处在于它表示程序中的精确内存位置。所有对静态的引用都指向同一个内存位置。

    【讨论】:

      【解决方案3】:

      没有。至于机器码,没有区别:

      static MY_STRUCT: SomeStruct = SomeStruct { value: 1 };
      fn get_static_ref() -> &'static SomeStruct {
          &MY_STRUCT
      }
      

      fn get_static_ref() -> &'static SomeStruct {
          static MY_STRUCT: SomeStruct = SomeStruct { value: 1 };
          &MY_STRUCT
      }
      

      在函数体内声明静态只是限制了名称的范围。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-10
        • 2019-05-02
        • 2020-04-02
        • 2021-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多