编译器如何处理具有更复杂值的枚举?

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

我曾经向我解释过这一点,但我对细节很模糊:所以当你有一个枚举时,比如说,在 C 中,枚举没有起始值,如下所示:

enum Level {  
LOW,   
MEDIUM,   
HIGH 
}; 

编译器只是为这些家伙分配任意整数值。即使您明确指定整数:

enum Level {  
LOW = 0,
MEDIUM = 1,   
HIGH = 2 
}; 

现在你只是在做编译器可能已经做的事情,但是是明确的。

但是更复杂的枚举呢,比如 Java 或 Rust 中的枚举呢?例如。来自 Rust 书的枚举部分:

enum IpAddr {
        V4(u8, u8, u8, u8),
        V6(String),
    }

很久以前向我解释时,我隐约记得有人提到这是通过使用 2 个结构来处理的,例如:

struct enums {

    0,  //arbitrary value used for V4

    1   //arbitrary value used for V6

}
struct values {

     u8 array[4],

     char * string

}

第一个结构体的任意值以某种方式映射到它们可以存储的值。我还记得向我解释它的人将此类枚举称为其中包含“记录”一词的术语。我在本网站或其他地方找不到任何提及此技术的信息,因此,如果有人可以解释它或至少告诉我要自己研究什么主题,我将不胜感激。

c rust enums record
1个回答
0
投票

在 C 语言中,最接近的等价形式是:

typedef enum {
  TAG_V4,
  TAG_V6,
} ip_addr_tag;

typedef struct {
  a: unsigned char;
  b: unsigned char;
  c: unsigned char;
  d: unsigned char;
} ip_addr_v4;

typedef struct {
  char* string
} ip_addr_v6;

typedef union {
  ip_addr_v4 v4;
  ip_addr_v6 v6;
} ip_addr_content;

// if `tag == TAG_V4`, you may use `content.v4`
// if `tag == TAG_V6`, you may use `content.v6`
typedef struct {  // implement a tagged union
  ip_addr_tag tag;
  ip_addr_content content;
} ip_addr;

有一些差异:

  • Rust 对于标签很聪明,例如如果它发现联合中未使用的字节,它将使用该字节来存储标签,而不是需要多一个字节来存储它;
  • Rust 的类型系统保证您正确使用标签/联合;
  • Rust 确保当你离开作用域时析构函数会运行。

我希望这有帮助!

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