Tipo de enumeración de unión: desde el lenguaje C para ver la enumeración y el tipo de unión a TypeScript / Python

La enumeración todavía se extrae de hello world. La mayoría de las personas deberían comenzar desde C, como yo. Por supuesto, esta parte también se puede omitir. 

Explique el tipo de enumeración en detalle:

Enum en lenguaje C

Me impresionó un poco cuando inicié la computadora:

Enum es una palabra clave en el lenguaje C y enum se denomina tipo de datos enumerados .

Un tipo enumerado es un tipo de datos que representa una constante entera. Con la palabra clave enum, puede crear un nuevo "tipo" y especificar su valor . La sintaxis de los tipos enumerados es similar a la de las estructuras.

¿Por qué necesita usar tipos enumerados?

En la programación real, el valor de algunos datos a menudo es limitado, solo puede ser un número muy pequeño de números enteros, y es mejor darle un nombre a cada valor para facilitar el uso en códigos posteriores, como solo siete días a la semana, uno El año es de solo doce meses y una clase tiene seis cursos por semana. Una orden tiene solo n estados.

Esto es lo que definimos uno por uno, lo que resultó en demasiados nombres de macro y código suelto, lo que siempre parece un poco incómodo.

#define Lun 1 var Lun = 1 
#define Mart 2 var Mar = 2 
#define Wed 3 var Wed = 3 
..... 
#define Sun 7 var Sun = 7

El propósito de diseñar tipos enumerados es mejorar la legibilidad del programa .

Forma de definición del tipo de enumeración

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

  • Enum es una nueva palabra clave utilizada específicamente para definir tipos enumerados, que también es su único uso en lenguaje C;

  • typeName es el nombre del tipo enumerado; valueName1, valueName2, valueName3, ... es una lista de nombres correspondientes a cada valor.

  • Los elementos (miembros de enumeración) en las llaves son constantes en lugar de variables. Esto debe quedar claro, ya que los miembros de enumeración son constantes, por lo que no puede asignarles valores, solo puede asignar sus valores a otras variables

Descripción del tipo de enumeración

Por ejemplo, para enumerar el día de la semana correspondiente al día de la semana:

enum week {lunes, martes, miércoles, jueves, viernes, sábado, domingo};

Como puede ver, solo dimos el nombre, pero no el valor correspondiente al nombre. Esto se debe a que el valor de enumeración comienza en 0 por defecto y luego aumenta en 1 (incremental) ; es decir, los lunes y martes de la semana. ...... Los valores correspondientes de Sun son 0, 1 ...... 6.

El valor de la constante de enumeración no se indica explícitamente. En ausencia de una descripción de visualización, la constante de enumeración toma por defecto el valor de la primera constante de enumeración como 0, y cada constante de enumeración se incrementa en 1 a su vez

También podemos asignar un valor a cada nombre:

semana enum {Lunes = 1, Martes = 2, Miércoles = 3, Jueves = 4, Viernes = 5, Sábado = 6, Sol = 7};

Una forma más sencilla es asignar solo un valor al nombre

semana de enumeración {Lun = 1, martes, miércoles, jueves, viernes, sábado, domingo};

De esta manera, el valor de la enumeración se incrementa de 1, que es equivalente a la escritura anterior.

El valor del nombre de enumeración no especificado se incrementará secuencialmente de acuerdo con el último valor especificado (tenga en cuenta que es el último valor especificado)

para resumir:

  1. En el caso de que no haya instrucciones de visualización, la constante de enumeración (es decir, el nombre de la constante entre llaves) toma por defecto el valor de la primera constante de enumeración, y luego cada constante de enumeración se incrementa en 1

  2. En el caso de descripciones de visualización parciales, el valor del nombre de enumeración no especificado se incrementará secuencialmente de acuerdo con el último valor especificado antes.

  3. No se puede asignar un número entero directamente a una variable de enumeración. El tipo de enumeración al que pertenece la variable de enumeración debe usarse para la coerción de tipo antes de la asignación

  4. Diferentes miembros de enumeración en el mismo tipo de enumeración pueden tener el mismo valor

  5. Los tipos de enumeración con el mismo nombre no se pueden definir en el mismo programa y los miembros de enumeración (constantes enum) con el mismo nombre no pueden existir en diferentes tipos de enumeración.

Variable enumerada

枚举类型变量不是一个包含若干个成员的集合,枚举类型变量和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。

Ejemplo de longitud del tipo de unión

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




Artículo del sitio reimpreso " Tipos enumerados conjuntos: del tipo de lenguaje C para ver la enumeración y unir el texto mecanografiado / Python ",
indique la fuente: https://www.zhoulujun.cn/html/webfront/ECMAScript/typescript/2020_0410_8368. html


Supongo que te gusta

Origin blog.51cto.com/zhoulujun/2535575
Recomendado
Clasificación