Union Enumeration Type: From C Language to View Enumeration and Union Type to TypeScript/Python

Enumeration is still drawn from hello world. Most people should start from C, such as me. Of course, this part can also be skipped. 

Explain the enumeration type in detail:

Enum in C language

I was a little bit impressed when I started computer:

Enum is a keyword in the C language, and enum is called an enumerated data type .

An enumerated type is a data type that represents an integer constant. With the keyword enum, you can create a new "type" and specify its value . The syntax of enumerated types is similar to that of structures.

Why do you need to use enumerated types

In actual programming, the value of some data is often limited, it can only be a very small number of integers, and it is best to give each value a name to facilitate use in subsequent codes, such as only seven days a week, one The year is only twelve months, and a class has six courses per week. An order has only n states.

This is what we defined one by one, resulting in too many macro names and loose code, which always looks a little uncomfortable.

#define Mon 1   var Mon =1
#define Tues 2  var Tues = 2
#define Wed 3   var Wed = 3
.....
#define Sun 7   var Sun = 7

The purpose of designing enumerated types is to improve the readability of the program .

Definition form of enumeration type

enum typeName{ valueName1, valueName2, valueName3, ...... };

  • Enum is a new keyword specifically used to define enumerated types, which is also its only use in C language;

  • typeName is the name of the enumerated type; valueName1, valueName2, valueName3, ... is a list of names corresponding to each value.

  • The elements (enumeration members) in the curly braces are constants rather than variables. This must be clear, because enumeration members are constants, so you can’t assign values ​​to them, you can only assign their values ​​to other variables

Enumeration type description

For example, to list the day of the week corresponding to the day of the week:

enum week{ Mon, Tues, Wed, Thurs, Fri, Sat, Sun };

As you can see, we only gave the name, but did not give the value corresponding to the name. This is because the enumeration value starts from 0 by default, and then increases by 1 (incremental) ; that is, Mon and Tues in the week ...... The corresponding values ​​of Sun are 0, 1 ...... 6.

The value of the enumeration constant is not explicitly stated. In the absence of a display description, the enumeration constant defaults to the value of the first enumeration constant as 0, and each enumeration constant is incremented by 1 in turn

We can also assign a value to each name:

enum week{ Mon = 1, Tues = 2, Wed = 3, Thurs = 4, Fri = 5, Sat = 6, Sun = 7 };

A simpler way is to only assign a value to the first name

enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };

In this way, the enumeration value is incremented from 1, which is equivalent to the above writing.

The value of the unspecified enumeration name will be incremented sequentially according to the last specified value (note that it is the last specified value)

to sum up:

  1. In the case of no display instructions, the enumeration constant (that is, the constant name in the curly braces) defaults to the value of the first enumeration constant, and then each enumeration constant is incremented by 1

  2. In the case of partial display descriptions, the value of the unspecified enumeration name will be incremented sequentially according to the last specified value before

  3. An integer cannot be directly assigned to an enumeration variable. The enumeration type to which the enumeration variable belongs must be used for type coercion before assignment

  4. Different enumeration members in the same enumeration type can have the same value

  5. Enumeration types with the same name cannot be defined in the same program, and enumeration members (enum constants) with the same name cannot exist in different enumeration types.

Enumerated variable

枚举类型变量不是一个包含若干个成员的集合,枚举类型变量和int、char类型的变量其实差不多,只不过枚举类型变量的赋值只能用自身的枚举成员来赋值,以上面的例子来说,

变量a、b、c等的赋值就只能用枚举成员Mon、Tues、Wed、Thurs,而不能用其他枚举类型的枚举成员来赋值

枚举是一种类型,通过它可以定义枚举变量:enum week a, b, c;  定义枚举类型的同时定义枚举变量

也可以在定义枚举类型的同时定义变量:enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } a, b, c; 先定义枚举类型,再定义枚举变量

有了枚举变量,就可以把列表中的值赋给它:

enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };
enum week a = Mon, b = Wed, c = Sat;

其它语言的枚举类型,都跟C语言差不多

联合(union)

联合(union)又称联合体或是共用体,是一个能在同一块存储空间中(但非同时)存储不同类型数据的数据类型。也就是说几种成员数据“共用”了同一块存储空间。

联合体的作用不光是节省存储空间那么简单,更重要的是为数据提供了一个统一的封装和外部访问的接口。C语言编译器保证了union的共用体的长度等于最长的成员的长度。

union的定义

union的定义形式为:

union 共用体名 { 类型名    成员名1;类型名    成员名2;类型名n    成员名n;};   

与枚举很像对不?联合类型,就是扩大了枚举的类型范围。union也可以声明为变量、数组、指针等等。比如:

union group {
    int    digit; 
    double myfloat;
    char   letter;
};

联合类型 共用体类型union group,它有3个成员,分别是int, char, double。由于double成员的长度最大,为8 Bytes,因此,共用体的长度也应为8 Bytes。

Example of union type length

C语言编译器保证了union的共用体的长度等于最长的成员的长度。

Typescript枚举类型enum

Typescript相比C语言,还有如如下特性

反向映射

我们可以通过 Enum[key] 或者 Enum.key 的方式获取到对应的值。typescript 还支持反向映射,即可以通过值来获取键,不过反向映射只支持数字枚举。下面是个例子:

enum Status {
  Success = 200,
  NotFound = 404,
  Error = 500}
console.log(Status.Success) // 200
console.log(Status[200]) // Success
console.log(Status[Status.Success]) // Success

比如状态码,相比 Map类型,枚举的值也可以取健,这是枚举的一个特殊用法

异构枚举

异构枚举是指,枚举可以混合字符串和数字成员,如:

enum Enum {
  A = 0,
  B = 'hello'}
console.log(Enum.A) // 0console.log(Enum.B) // hello

这个只有弱类型语言才会有异构枚举。C语言枚举支持整形。python 可以通过引入 from enum import IntEnum  限定。其实,这个C语言的Union 联合类型不是很像吗。

枚举成员类型和联合枚举类型

如果一个枚举里所有成员的值都是字面量类型的值,那么这个枚举的每个成员和枚举本身都可以作为类型来使用

字面量枚举成员需满足以下条件:

  • 不带初始值的枚举成员,例如 enum E { A }

  • 值为字符串字面量,例如 enum E { A = 'hello' }

  • 值为数字字面量,或者带有一元运算符 +, -, ~其中之一的符号的数字字面量,例如 enum E { A = 1 },enum E { A = -1 }

  • 当以上的条件均不满足的情况下,枚举成员被当作是需要计算得出的值:enum OrderStatus{ A, B = 1 << 1,C=A||B ,G = "s".length }

枚举成员类型

把符合条件的枚举成员作为类型来使用,例子:

enum ShapeKind {
  Circle,
  Square
}

interface Circle {
  kind: ShapeKind.Circle // 使用 ShapeKind.Circle 作为类型,指定接口须有 kind 字段,且类型为 ShapeKind.Circle
  radius: number
}

interface Square {
  kind: ShapeKind.Square // 同上
  sideLength: number
}

let c: Circle = {
  kind: ShapeKind.Square, // Error! 因为接口 Circle 的 kind 被指定为 ShapeKind.Circle类型,所以这里会报错
  radius: 100
}

我的理解就是枚举的值 不是基本变量。

联合枚举类型

C语言中,我是没有使用过联合枚举类型。联合就是联合,枚举就是枚举。这个是TypeScript的杂交品种。我也是不求甚解,照搬一下例子

// 枚举 Status 里有两个状态
enum Status {
  Off,
  On
}

// 枚举 Animal 里有两个动物
enum Animal {
  Cat,
  Dog
}

// 接口 Light 中定义 status字段,它是 Status 类型,可以是 Off 或者 On 状态
interface Light {
  status: Status
}

let lg1: Light = {
  status: Status.Off // 正确
}

let lg2: Light = {
  status: Animal.Cat // error 不能将类型 Animal.Cat 分配给类型 Status
}

求大神赐教

运行时的枚举-Enums at runtime||compile time

枚举是在运行时真正存在的对象,可以把枚举当作对象使用:

enum E {
  A,
  B
}

function func(obj: { A: number }): number {
  return obj.A
}

console.log(func(E)) // 0

代码中,声明了一个函数 func,它的参数是一个对象,且必须包含属性名为 A 的属性,A 的值为数值类型。当调用函数 func 时,把枚举 E 当作符合条件的实参传入,正确运行。

常量枚举-const enum

在某种情况下,枚举和枚举成员都可以作为一种单独的类型存在(枚举成员没有初始值 / 所有成员都为数字枚举 / 所有成员均为字符串枚举)

其定义的枚举,在经过编译器编译后是一个对象,这个对象我们可以在程序运行时使用,前面有说到。但有时定义枚举可能只是为了让程序可读性更好,而不需要编译后的代码,即不需要编译成对象。typescript中考虑到这种情况,所以加入了 const enum (完全嵌入的枚举)。typescript官网有一个在线编译器,来看看下面的例子:

enum Status{
    Off,
    On
}

const enum Animal{
    Dog,
    Cat
}

const status = Status.On
const animal = Animal.Dog

这段代码编译成JavaScript后是这样的:

var Status;
(function (Status) {
    Status[Status["Off"] = 0] = "Off";
    Status[Status["On"] = 1] = "On";
})(Status || (Status = {}));
var status = Status.On;
var animal = 0 /* Dog */;

可以看到编译后的代码中并没有像创建Status一样创建了Animal,而是直接把 Animal 中 Dog 值 0 替换到表达式中 Animal.Dog 的位置,这样就节省了生成代码的开销。

python枚举类型

enum模块是系统内置模块,可以直接使用import导入,但是在导入的时候,不建议使用import enum将enum模块中的所有数据都导入,一般使用的最多的就是enum模块中的Enum、IntEnum、unique这几项

# 导入枚举类
from enum import Enum
 
# 继承枚举类
class color(Enum):
    YELLOW  = 1
    BEOWN   = 1 
    # 注意BROWN的值和YELLOW的值相同,这是允许的,此时的BROWN相当于YELLOW的别名
    RED     = 2
    GREEN   = 3
    PINK    = 4

枚举和我们在对象中定义的类变量时一样的,每一个类变量就是一个枚举项,访问枚举项的方式为:类名加上类变量。但是不适用系统自带的枚举,而是普通类。会存在如下问题:

  • 枚举类中,不应该存在key相同的枚举项(类变量)

  • 不允许在类外直接修改枚举项的值

python枚举不像C语言,枚举成员变量值只能是整形,同为弱类型语言,与TypeScript不同的是,没有异构枚举,

  • 如果要枚举类中的Value只能是整型数字,那么,可以导入IntEnum,然后继承IntEnum即可

    from enum import IntEnum //注意,此时,如果value为字符串的数字,也不会报错

  • 如果要枚举类中的key也不能相同,那么在导入Enum的同时,需要导入unique函数

    from enum import Enum, uniqu

参考资料:

C语言枚举类型(C语言enum用法)详解 c.biancheng.net/view/2034.html

枚举类型enum详解——C语言 https://www.cnblogs.com/lanhaicode/p/10620028.html

【C语言】联合与枚举类型 https://blog.csdn.net/tracer9/article/details/50382370

关于typescript中的枚举你需要知道这些 https://www.cnblogs.com/wjaaron/p/11672764.html




Reprinted site article " Joint enumerated types: from the C language type to see enumeration and joint the typescript / Python ",
please indicate the source: https://www.zhoulujun.cn/html/webfront/ECMAScript/typescript/2020_0410_8368. html


Guess you like

Origin blog.51cto.com/zhoulujun/2535575