为什么大小是一个lazy_static!符号表中的变量为零?

问题描述 投票:0回答:1

我有以下针对 x86_64 的 Rust 代码:

#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<u32, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0, "foo");
        m.insert(1, "bar");
        m.insert(2, "baz");
        m
    };
}

fn main() {
    // First access to `HASHMAP` initializes it
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());

    // Any further access to `HASHMAP` just returns the computed value
    println!("The entry for `1` is \"{}\".", HASHMAP.get(&1).unwrap());
}

我使用

readelf
命令查看符号表中
HASHMAP
变量的大小:

readelf -sW target/debug/deps/section_test-4d7d6a03c56fdde3.o

Symbol table '.symtab' contains 590 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
452: 0000000000000000     0 OBJECT  LOCAL  DEFAULT  498 _ZN12section_test7HASHMAP17hbc6de818c577d166E

我们可以看到尺寸为0。

readelf -SW target/debug/deps/section_test-4d7d6a03c56fdde3.o
There are 527 section headers, starting at offset 0x98690:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
 [498] .rodata._ZN12section_test7HASHMAP17hbc6de818c577d166E PROGBITS        0000000000000000 00b528 000000 00   A  0   0  1

该符号位于

rodata
部分,该部分的大小也为0。

既然长度为0,是不是就代表不能存储数据了?运行时分配的

HashMap
内存在哪里?

rust symbols elf lazy-static
1个回答
5
投票

lazy_static
创建一个空类型和值,相当于:

struct HASHMAP { __private_field: ()}
static HASHMAP: HASHMAP = HASHMAP { __private_field: () }

(源码)

然后它为此类型实现

Deref
,以便在您第一次尝试访问它时可以动态初始化实际值(实际值隐藏在由
deref
调用的私有函数内的静态值中)。

顺便说一句,请注意,当

HashMap
初始化时,键和值将被分配并存储在堆上,只有
HashMap
结构本身位于隐藏的静态值中。

© www.soinside.com 2019 - 2024. All rights reserved.