枚举,还是从hello world 开奖,大部分的人应该是从C开始的,比如我。当然,这部分也可以跳过。

详说枚举类型:

C语言中的enum

计算机入门时候有点印象:

enum是C语言中的一个关键字,enum叫枚举数据类型

枚举类型(enumerated type)是一种代表整数常量的数据类型。通过关键字enum,可以创建一个新“类型”并指定它的值。枚举类型的语法与结构体的语法相类似。

为什么需要使用枚举类型

在实际编程中,有些数据的取值往往是有限的,只能是非常少量的整数,并且最好为每个值都取一个名字,以方便在后续代码中使用,比如一个星期只有七天,一年只有十二个月,一个班每周有六门课程等。一个订单只有n个状态。

这是我们我们一一定义,导致宏名过多,代码松散,看起来总有点不舒服。

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

设计枚举类型的目的在于提高程序的可读性

枚举类型的定义形式

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

  • enum是一个新的关键字,专门用来定义枚举类型,这也是它在C语言中的唯一用途;

  • typeName是枚举类型的名字;valueName1, valueName2, valueName3, ......是每个值对应的名字的列表。

  • 花括号里面的元素(枚举成员)是常量而不是变量,这个一定要搞清楚,因为枚举成员的是常量,所以不能对它们赋值,只能将它们的值赋给其他的变量

例如,列出一个星期第几天对应星期几:

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

可以看到,我们仅仅给出了名字,却没有给出名字对应的值,这是因为枚举值默认从 0 开始,往后逐个加 1(递增);也就是说,week 中的 Mon、Tues ...... Sun 对应的值分别为 0、1 ...... 6。

不显式说明枚举常量的值,在没有显示说明的情况下,枚举常量默认第一个枚举常量的值为0,往后每个枚举常量依次递增1

我们也可以给每个名字都指定一个值:

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

更为简单的方法是只给第一个名字指定值

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

这样枚举值就从 1 开始递增,跟上面的写法是等效的。

未指定的枚举名的值将依着最后一个指定值向后依次递增(注意是最后一个指定值)

总结:

  1. 在没有显示说明的情况下,枚举常量(也就是花括号中的常量名)默认第一个枚举常量的值为0,往后每个枚举常量依次递增1

  2. 在部分显示说明的情况下,未指定的枚举名的值将依着之前最有一个指定值向后依次递增

  3. 一个整数不能直接赋值给一个枚举变量,必须用该枚举变量所属的枚举类型进行类型强制转换后才能赋值

  4. 同一枚举类型中不同的枚举成员可以具有相同的值

  5. 同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的枚举成员(枚举常量)

枚举类型变量

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

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

转载本站文章《联合枚举类型:从C语言看枚举与联合类型到TypeScript/Python》,
请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/typescript/2020_0410_8368.html

联合枚举类型:从C语言看枚举与联合类型到TypeScript/Python的更多相关文章

  1. C语言中结构、联合、枚举的说明

    复杂的数据类型 一般的步骤: 1.声明模板 2.定义变量,分配内存空间 3.初始化 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ...

  2. 黑马程序员——C语言基础 枚举 宏定义 自定义 static exterm

    Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结) (一)枚举 1)枚举类型的定义 枚举是C语言中的一种基本数据类型,并不是构 ...

  3. C语言之枚举数据类型

    枚举数据类型概述:1.枚举类型是C语言的一种构造类型.它用于声明一组命名的常数,2.当一个变量有几种可能的取值时,可以将它定义为枚举类型.3.枚举类型是由用户自定义的由多个命名枚举常量构成的类型,其声 ...

  4. Swift 枚举-从汇编角度看枚举内存结构

    一.基本使用 先看枚举的几种使用(暂不要问,看看是否都能看懂,待会会逐一讲解) 1.操作一 简单使用 //第一种方式 enum Direction { case east case west case ...

  5. C语言的结构和联合,以及PHP是怎么实现弱类型的

    C语言的结构(struct):包含多个成员,可能有多种数据类型,并且需要分配几种类型占用空间之和的空间. 联合(union):支持多种类型,供使用者使用其中一种数据类型,当然是需要分配其中占用空间最大 ...

  6. 编写高质量代码改善C#程序的157个建议——建议130:以复数命名枚举类型,以单数命名枚举元素

    建议130:以复数命名枚举类型,以单数命名枚举元素 枚举类型应该具有负数形式,它表达的是将一组相关元素组合起来的语义.比如: enum Week { Monday, Tuesday, Wednesda ...

  7. C语言入门-枚举

    常量符号化 用符号而不是具体的数字来表示程序中的数字 一. 枚举 用枚举而不是定义独立的const int变量 枚举是一种用户定义的数据类型,它用关键字enum如以下语句来声明 enum 枚举类型名字 ...

  8. java基本类型、数组、和枚举类型

    开始之前先吐槽一下,学艺不精,面试要吃大亏,出来混迟早要还的. 别的不说了,从零开始复习基础知识 1.标识符和关键字 意义:标识符用于对变量.类.和方法的命名.规范的标识符命名可以提高程序的可读取性. ...

  9. c语言基础学习09_复合类型

    =============================================================================涉及到的知识点有:一.结构体1.定义结构体st ...

  10. 智能合约语言 Solidity 教程系列1 - 类型介绍

    现在的Solidity中文文档,要么翻译的太烂,要么太旧,决定重新翻译下.尤其点名批评极客学院名为<Solidity官方文档中文版>的翻译,机器翻译的都比它好,大家还是别看了. 写在前面 ...

随机推荐

  1. np.array和np.ndarry 的区别

    np.array和np.ndarray都是NumPy中用于创建多维数组的函数. np.ndarray是NumPy中的多维数组类,它是一种可变的数组,可以通过修改数组中的元素来改变其内容.使用np.nd ...

  2. FreeSWITCH的moh使用笔记

    操作系统 :CentOS 7.6_x64 FreeSWITCH版本 :1.10.9 之前写过FreeSWITCH安装的文章,今天整理下moh使用过程中遇到的问题及解决方案,并提供moh音频下载途径.F ...

  3. [Python急救站课程]Python集成环境IDEA:Pycham专业版2023.2.3安装与破解方法

    今天给大家带来了我们的第一课内容,Pycharm专业版2023.2.3安装并破解 首先,在浏览器中搜索Pycharm即可进入官网下载:https://www.jetbrains.com/pycharm ...

  4. 神经网络基础篇:Python 中的广播(Broadcasting in Python)

    Python 中的广播 这是一个不同食物(每100g)中不同营养成分的卡路里含量表格,表格为3行4列,列表示不同的食物种类,从左至右依次为苹果,牛肉,鸡蛋,土豆.行表示不同的营养成分,从上到下依次为碳 ...

  5. VUE首屏加载优化 性能优化分析插件安装分享

    优化背景: 项目上线后 第一次进入项目要等待接近50s才能进入页面.一开始觉得是电脑配置问题或者网络问题.F12后发现加载资源过慢 其中一个chunk-***js文件有10m 加载了45s .我们使用 ...

  6. 27. 干货系列从零用Rust编写正反向代理,Rust中日志库的应用基础准备

    wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,内网穿透,后续将实现websocket代理等,会将实现 ...

  7. UVA529 加成序列

    传送门 题目分析 一道 dfs,迭代加深 我们可以很快的猜出来最终 \(m\) 的长度必然是小于 \(10\) 的. 而这种浅深度的问题正好适用于迭代加深. 之后考虑剪枝 优化搜索顺序 : 我们要让序 ...

  8. 2020年第十一届蓝桥杯第二场C/C++ B组省赛题解

    2020年第十一届蓝桥杯C/C++ B组省赛题解 试题A:门牌制作 [问题描述] 小蓝要为一条街的住户制作门牌号. 这条街一共有 \(2020\) 位住户,门牌号从 \(1\) 到 \(2020\) ...

  9. 信创就用国产的 Solon Java Framework,v2.6.0 发布

    先吹牛! 在 v2.6 这个新的里程碑节点,Solon 又完成了几件惊天大事(每一件,都是经历了漫长时间打磨与积累): (1)Solon Native,有了第一个开源案例:dromara/neutri ...

  10. httpclients 和 okhttp 区别

    HttpClient使用介绍使用HttpClient发送请求主要分为以下几步骤: 创建 CloseableHttpClient对象或CloseableHttpAsyncClient对象,前者同步,后者 ...