cnoder
V2EX  ›  程序员

枚举类型是从 0 开始还是从 1 开始

By cnoder at 2022 年 7 月 22 日 · 8901 次点击

起因:那天听到前端 leader 在阴阳怪气我设计的枚举不是从 0 开始,跟旁边的人说什么“但凡学过 java 。。。。。也应该知道。。。”云云

我(我是后端)也没和他辩解

我说下我的理由吧

  1. 如果用 int 来代表 true/false ,我会设计为 0/1
  2. 如果是几种状态值,我会选择从 1 开始,避免选择 0 。因为某些弱类型语言在判断 0 的时候会自动做类型转换,而且我们目前业务上使用的后端语言也是 lua ,数组索引是从 1 开始的。

所以我在跟前端定义参数的时候 选择 1 、2 、3 来表示样式 123 。

我这理由充分嘛?

第 1 条附言  ·  2022 年 7 月 22 日

是ios.leader他在和web.leader这么说,web他就在那附和。。。

事情其实过去已经一周了。只是我老看到他俩就想起来

弱类型语言我说的是php

94 条回复  •  2022-07-26 10:06:43 +08:00
coderluan
   1
coderluan  
   2022 年 7 月 22 日
不充分,完全不能解释为啥你不和他辩解。
villivateur
   2
villivateur  
   2022 年 7 月 22 日 via Android   ❤️ 4
如果单论语言设计的话,我所了解的 enum 都是默认从 0 开始的
timethinker
   3
timethinker  
   2022 年 7 月 22 日
前后端统一就行(意味着有一个文档来进行维护,类似字典),至于值是什么在编写代码的时候无关紧要,值只有在传输或者存储的时候才会被用到。不同语言的对于枚举这个东西定义还不一样,不过逻辑上来讲枚举通常意义下就是一个有限的集合,这个集合里面定义的每一个枚举单位都是独一无二的,这样就可以借助语言的特性来进行一些约束性的操作。
bootvue
   4
bootvue  
   2022 年 7 月 22 日
从几开始关他屁事
icebay
   5
icebay  
   2022 年 7 月 22 日
但凡写过项目,就知道从几开始关他屁事
lanlanye
   6
lanlanye  
   2022 年 7 月 22 日   ❤️ 3
我记得 Uber 的 Golang 风格里提到过建议从 1 开始,理由和你说的一样
wowawesome
   7
wowawesome  
   2022 年 7 月 22 日
直接叼他,从几开始关你屁事,看劳资的接口文档用就行了。
ezrealinxh
   8
ezrealinxh  
   2022 年 7 月 22 日   ❤️ 13
下次给他从 999 开始倒着来
menc
   9
menc  
   2022 年 7 月 22 日
scala 的 tuple 类型下标就是从 1 开始的,你可以回一个阴阳怪气,“但凡学过 scala ,也应该知道....”
menc
   10
menc  
   2022 年 7 月 22 日   ❤️ 1
https://en.wikipedia.org/wiki/Comparison_of_programming_languages_%28array%29#Array_system_cross-reference_list

从这里可以看到 array 下标的起始值 0 和 1 五五开,你 leader 还是太 naive
sadfQED2
   11
sadfQED2  
   2022 年 7 月 22 日 via Android
我一般也喜欢从 1 开始,因为 0 是默认值,用 0 当枚举偶尔出错忘了赋值的时候都不容易发现
HOU
   12
HOU  
   2022 年 7 月 22 日
叼他完了,你的设计没错,管的真宽
marcong95
   13
marcong95  
   2022 年 7 月 22 日
@menc #10 然而你给的链接里 Scale 的下标是 0 开始的,这就十分有趣了
dqzcwxb
   14
dqzcwxb  
   2022 年 7 月 22 日
现在你可以把大家提供的资料甩他脸上,美其名曰"技术分享"
SuperMild
   15
SuperMild  
   2022 年 7 月 22 日 via Android
提醒:不是数组,是枚举。
libook
   16
libook  
   2022 年 7 月 22 日
既然 Lua 默认从 1 开始,你就把 Lua 的文档丢给他,说“但凡多了解几门语言也应该知道不一定都从 0 开始。”

不管从几开始,这个是涉及到前后端协商标准的问题,后端不需要为前端考虑太多,前端也不需要为后端考虑太多,严格按照约定的标准自己管好自己就好了,否则就容易好心当成驴肝肺。

一个人对一个事物越是不了解,就越会使用过往经验和思维定式去揣测,吐槽者此举无疑暴漏了自己的无知,就像那个认为火箭应该用水洗煤的民科一样。
xz410236056
   17
xz410236056  
   2022 年 7 月 22 日
用 swift ,告诉他,枚举是可以没有初始值的,既不是 0 也不是 1
ysc3839
   18
ysc3839  
   2022 年 7 月 22 日 via Android   ❤️ 1
我会用 0 来表示一些特殊值,比如说是读取配置文件,把字符串转成枚举的话,我会把 0 设为 Unknown ,字符串错误的话就是 Unknown 。
RainCats
   19
RainCats  
   2022 年 7 月 22 日
枚举的索引确实是从 0 开始的,但自己定的 code 值看各人风格了,现在我吸取教训一般都是一开始定义时就 10 、20 、30 这样递增。。
wangtian2020
   20
wangtian2020  
   2022 年 7 月 22 日   ❤️ 4
我有交付的一个项目,枚举值是“↑ ↓ ← →”
IGJacklove
   21
IGJacklove  
   2022 年 7 月 22 日 via iPhone   ❤️ 3
他就是想怼你而已,从几开始根本不重要。你别陷入吃几碗粉的局。
sardina
   22
sardina  
   2022 年 7 月 22 日 via iPhone
@lanlanye go 是因为 int 默认为 0 所以建议 1 开始
lisongeee
   23
lisongeee  
   2022 年 7 月 22 日
可以从 1000 开始,这样 toString(10).length 是相等的,好对齐
xz410236056
   24
xz410236056  
   2022 年 7 月 22 日
@sardina #22 go 所谓的枚举不是用 iota 做初始值的吗?
nekoneko
   25
nekoneko  
   2022 年 7 月 22 日
我一般 0 禁用 1 启用 -1 删除, 其他枚举从 1 开始, 从 0 开始感觉怪怪的
keenkiller
   26
keenkiller  
   2022 年 7 月 22 日
混邪做法:用字符串
hopingtop
   27
hopingtop  
   2022 年 7 月 22 日
Golang 里面 用 iota 枚举, 但是我喜欢用 X = iota + 1 来设置枚举值,经验之谈,可以避免很多问题。杠就是你对
weiwenhao
   28
weiwenhao  
   2022 年 7 月 22 日
typedef enum {
FOO = 1,
BAR,
CAR
} t;

c 语言里面某些情况也是默认 0 , 所以推荐从 1 开始
kera0a
   29
kera0a  
   2022 年 7 月 22 日
要不是今年行情不好, 我就劝你离职了。
枚举值从几开始都能斗起来,工作氛围是多差啊
MuXia
   30
MuXia  
   2022 年 7 月 22 日
@wangtian2020 #20 看了一圈下来,还是你这个离谱
456789
   31
456789  
   2022 年 7 月 22 日
有个领导说我 mq 的 top 设置的太长运行中费内存,我看了他一眼说:你说的对,那有 bug 你来改
456789
   32
456789  
   2022 年 7 月 22 日
topic
bxb100
   33
bxb100  
   2022 年 7 月 22 日
@wangtian2020 太离谱了,你做的是手柄映射啊
lakehylia
   34
lakehylia  
   2022 年 7 月 22 日
我都是 4 个 char 凑成一个 int 当成枚举值,这样跟别人合并代码的时候,就完全不用枚举值会冲突了。比如
#define MAKE_ENUM_VALUE(a, b, c, d) ((int)(((unsigned int)(a)) | ((unsigned int)(b) << 8u) | ((unsigned int)(c) << 16u) | ((unsigned int)(d) << 24u)))
#define EOF MAKE_ENUM_VALUE( 'E','O','F',' ')
#define PLAYING MAKE_ENUM_VALUE( 'P','L','A','Y')

enum {
S_EOF = EOF,
S_PLAYING = PLAYING,
} status;
pastor
   35
pastor  
   2022 年 7 月 22 日
枚举本来就不是啥好玩意,明码标价各个值才方便阅读、日志。
同意的请点赞给我加分!
Huelse
   36
Huelse  
   2022 年 7 月 22 日
我也喜欢从 1 开始,0 的隐含意义太多,文档就算是约定了也还要自查一遍才能理清
itechnology
   37
itechnology  
   2022 年 7 月 22 日
讲道理,枚举从几开始关他什么事情,就这点事情他也要阴阳怪气,我建议你赶紧离职或者换个项目组
NGXDLK
   38
NGXDLK  
   2022 年 7 月 22 日
枚举从 0 还是 1 开始也能拿出来说?我还从 100 开始呢,这 leader 怕不是傻屌大学毕业的
pkoukk
   39
pkoukk  
   2022 年 7 月 22 日
@xz410236056 可以用 iota+1 做初始值
IvanLi127
   40
IvanLi127  
   2022 年 7 月 22 日
我认为枚举类型内部的表示方式不应该暴露给外部,交互的时候应该用字面值传递,而不是用整数。
YouRTBUG
   41
YouRTBUG  
   2022 年 7 月 22 日
就这也是 leader ?
molvqingtai
   42
molvqingtai  
   2022 年 7 月 22 日 via Android
我写前端使用 -1 表示全部🐶
BeautifulSoap
   43
BeautifulSoap  
   2022 年 7 月 22 日 via Android
都用枚举了还在乎起始值?直接给他来个 99 起,专治不服
maybe0410
   44
maybe0410  
   2022 年 7 月 22 日
我一般 100 ,200 ,300🐶
catsoul
   45
catsoul  
   2022 年 7 月 22 日
@BeautifulSoap 雀食,枚举就别跟其他的混了,直接 100 起跳
Building
   46
Building  
   2022 年 7 月 22 日 via iPhone
枚举值和属性值绑定,随便
枚举值和属性值无关,还是随便
但我喜欢有默认值的时候在 0 位放默认值,没有默认值用 none
stevefan1999
   47
stevefan1999  
   2022 年 7 月 22 日 via Android
不要爭論這個問題

lua 壬震怒(我不是)

實際上 lua 是沒有定義索引方向 但社羣定義是 1 開始

0 開始還是 1 開始 蘊含了 offset 與 absolute positon 黨派之爭 我個人讀算法時是支持 1 開始的 但實際上用還是最好得 0
potatowish
   48
potatowish  
   2022 年 7 月 22 日 via iPhone
不要和前端、客户端讨论后端的问题,和一个外行讨论技术问题就是浪费时间。
akagishigeru
   49
akagishigeru  
   2022 年 7 月 22 日 via iPhone
你的理由是对的,前端的确有这种情况
wktrf
   50
wktrf  
   2022 年 7 月 22 日
作为前端我也喜欢用 1 开始,0 很容易疏忽导致判断出现问题
lucays
   51
lucays  
   2022 年 7 月 22 日
作为写 python 的,除非枚举就俩,否则肯定从 1 开始
mmdsun
   52
mmdsun  
   2022 年 7 月 22 日
有设计文档说应该从 1 开始不过有争论。有个例子:Mysql 的枚举是从 1 开始的,0 会报错。

文档写: (✔)
0 ,保留字
1 ,状态 1
2 ,状态 2

文档: ( X )
1 ,状态 1
2 ,状态 2
buxudashi
   53
buxudashi  
   2022 年 7 月 22 日
1 就是 1.而 0 就不一定了。有时 false,null,空字符串,empty(),什么乱七八糟的相通。

所以你是对的。
elevioux
   54
elevioux  
   2022 年 7 月 22 日 via Android
php 开发,从 1 开始,理由一样
xiubin
   55
xiubin  
   2022 年 7 月 22 日
从 0 开始,0 是无业务意义或者默认的一档,比如 0 可以是:unknow 、none 、default 、normal 。

iOS 开发( OC 语言)一般无法识别 nil 0 null 的区别
mengzhuo
   56
mengzhuo  
   2022 年 7 月 22 日
枚举的话,0 一般是非法(就是防止协议解析失败)
byzod
   57
byzod  
   2022 年 7 月 22 日
标准答案:关你卵事,我从 114514 开始
FrankHB
   58
FrankHB  
   2022 年 7 月 22 日
下标的问题,只能说历史丈育太多,典都不知道,还用得着举例了:www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html
Lua ?算哪根葱……况且 Lua 用户自己很多就不满意:lua-users.org/wiki/CountingFromOne
再有争议可能还是数学丈育更多,分不清基数和序数。

至于枚举……谁告诉你枚举就非得有从几开始的问题?
还是 C 枚举当整数,于是随便什么语言都需要关心编码?
( Swift:?)
而且咋不学 C 把 char 也整成整数类型呢?

@byzod 太臭了,要肛掉。
icyalala
   59
icyalala  
   2022 年 7 月 22 日   ❤️ 1
如果是 enum 关联到整数,那我还是倾向从 0 开始,0 就是一个默认值。
lua 那个设计 table 就是从 1 开始的,所以 enum 从 1 开始也算符合他们的习惯。
其他不少语言 enum 可以不关联到整数,那就不用争了。
zm8m93Q1e5otOC69
   60
zm8m93Q1e5otOC69  
   2022 年 7 月 22 日
想从多少就多少呗,写清楚不就行了。。咋还有这种领导。。
dumbass
   61
dumbass  
   2022 年 7 月 22 日 via iPhone
别的不知道,反正我们的 go 后端用 1 表示有,2 表示没有
Leviathann
   62
Leviathann  
   2022 年 7 月 22 日
为什么不是直接序列化成字符串
banricho
   63
banricho  
   2022 年 7 月 22 日
为啥要让前端知道数字
接口里看到不是字符串而是一堆数字搭配文档的,是我也要阴阳怪气
ikaros
   64
ikaros  
   2022 年 7 月 22 日
有些语言从 0 开始会有问题(golang), 所以从 1 开始准没错
blankmiss
   65
blankmiss  
   2022 年 7 月 22 日
@wangtian2020 我靠 这是什么操作
Helsing
   66
Helsing  
   2022 年 7 月 22 日 via iPhone
习惯确实是从 0 开始,你从 1 开始的理由没有说服力
aMR
   67
aMR  
   2022 年 7 月 22 日
当然是互相妥协一下从 0.5 开始 ε=ε=ε=┏(゜ロ゜;)┛

实际项目中,可以在枚举值最前面加入一个 Invalid\Undefined 的默认枚举值,既满足了从 0 开始,又可以防止有人没初始化搞出奇怪结果
iseki
   68
iseki  
   2022 年 7 月 23 日 via Android
哈,通讯时只要不是紧凑的二进制协议,我倾向于用字符串当枚举值~人类可读,易调试,看见就知道啥意思不用查表
Aloento
   69
Aloento  
   2022 年 7 月 23 日
枚举从多少开始这不就是看心情的事情吗(
xumng123
   70
xumng123  
   2022 年 7 月 23 日 via iPhone
0
Chingim
   71
Chingim  
   2022 年 7 月 23 日 via iPhone   ❤️ 1
枚举值本来就是无序的有限的状态集合,哪有什么“从哪开始”的说法

抛开具体语言,枚举值不仅仅只能用数字表示,难道用字符表示枚举,还得从 A 开始吗?
zed1018
   72
zed1018  
   2022 年 7 月 23 日
使用数字作为枚举值 ×
使用单词作为枚举值 √

我可不想看着字段脑子里还要加载翻译器 (逃
xaplux
   73
xaplux  
   2022 年 7 月 23 日
前几天我们前端也问我来着,说数据字典可以从 0 开始么,我说 0 有特殊含义,不可以,她也就没有再问,猜测数据字典一般用于下拉列表,从 0 开始前端方便处理吧
ydpro
   74
ydpro  
   2022 年 7 月 23 日
单纯想怼你就是了,下次枚举用雪花算法生成
Lirika
   75
Lirika  
   2022 年 7 月 23 日
我习惯从 0 开始
使用的时候可以声明一个数组$a=['a','b','c']
然后用你返回的枚举就直接取出来 $a[枚举值]
iColdCat
   76
iColdCat  
   2022 年 7 月 23 日
下次给他设计随机数 惯丫毛病
skinny
   77
skinny  
   2022 年 7 月 23 日
除了可以组合状态的枚举类型,不是一般用有意义的字符串名字吗?前端拿到的、发送的也是字符串,这样比较容易理解吧
brader
   78
brader  
   2022 年 7 月 23 日
我就比较叼了,这东西都是随缘的,今天想从 0 开始就从 0 ,明天想从 1 开始就从 1
brader
   79
brader  
   2022 年 7 月 23 日
我有时候还是从-1 开始的,哈哈,完全看心情
brader
   80
brader  
   2022 年 7 月 23 日
@skinny 枚举的键一般是没有什么展示意义的,只要保证唯一即可,对外用户展示的会有一个对应的中文名称。所以枚举值在英文或数字都可的场景下,后端一般会选择数字,是因为数据库存储 tinyint 更高效
rb6221
   81
rb6221  
   2022 年 7 月 23 日
这没什么对错,没必要争啊,自己喜欢用什么就用什么
tf2
   82
tf2  
   2022 年 7 月 23 日
你就说做一个异常占位的枚举为 0 。正常的都是 1 2 3 开始。
MEIerer
   83
MEIerer  
   2022 年 7 月 23 日 via Android
充分个毛,不都是 0 开始你吗,那些弱类型语言别人写的时候自然会进行判断
MEIerer
   84
MEIerer  
   2022 年 7 月 23 日 via Android
不过写好文档的话当我没说
changnet
   85
changnet  
   2022 年 7 月 23 日
就我而言,枚举从 0 开始,但业务逻辑一般是从 1 开始,0 是一个特殊值或者预留的,之前经常看到业务逻辑直接从 0 开始的,后面再定义一个特殊值会非常麻烦,比如
enum Type
{
None = 0, // 未指定
FOO = 1 // 业务逻辑的定义
}
WilliamYang
   86
WilliamYang  
   2022 年 7 月 23 日   ❤️ 1
写 protobuf 时,一般枚举第一个都是 UNKNOWN ,除非 0 值是本身是有意义的,否则就从 1 开始。嗯,你领导是垃圾
dingyaguang117
   87
dingyaguang117  
   2022 年 7 月 23 日
绝大多数情况都建议从 1 开始,0 留给未指定
dingyaguang117
   88
dingyaguang117  
   2022 年 7 月 23 日
枚举还要考虑入库的场景呢, 如果 0 是有意义的, 未收集 /未指定 只能用 null 了。 对于静态类型语言是无尽的烦恼
shawnsh
   89
shawnsh  
   2022 年 7 月 23 日 via Android
从几开始不用太关注吧
DoveAz
   90
DoveAz  
   2022 年 7 月 23 日
为了避免不必要的 bug ,最好从 0 开始 🐶
wdhwg001
   91
wdhwg001  
   2022 年 7 月 23 日
这里最佳实践是直接不给枚举的 0 值定义,并且任由它崩溃。

然后在文档里写明 0 值是 Invalid 的,但是代码里不需要把 0 值起名字为 Invalid ,而是直接从 1 开始,跳过 0 。

这样一来,那些没有赋值的枚举们就会直接崩溃,而代码也只需要在入口的地方处理掉这些 0 们,而不是每次写判断的时候脑子里都要带着这个 Invalid 。
DeWjjj
   92
DeWjjj  
PRO
   2022 年 7 月 23 日
默认 = 0 ,部分特定写 1 。
文档里面都有,给什么写什么。
ppllss
   93
ppllss  
   2022 年 7 月 25 日
从 0 开始
menc
   94
menc  
   2022 年 7 月 26 日
@marcong95 数组和 tuple 是两回事
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
© 2026 V2EX · 290ms · 3.9.8.5