V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cnoder
V2EX  ›  程序员

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

  •  
  •   cnoder · 2022-07-22 14:58:54 +08:00 · 7161 次点击
    这是一个创建于 856 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    我说下我的理由吧

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

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

    我这理由充分嘛?

    第 1 条附言  ·  2022-07-22 17:52:20 +08:00

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

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

    弱类型语言我说的是php

    94 条回复    2022-07-26 10:06:43 +08:00
    coderluan
        1
    coderluan  
       2022-07-22 15:05:05 +08:00
    不充分,完全不能解释为啥你不和他辩解。
    villivateur
        2
    villivateur  
       2022-07-22 15:07:18 +08:00 via Android   ❤️ 4
    如果单论语言设计的话,我所了解的 enum 都是默认从 0 开始的
    timethinker
        3
    timethinker  
       2022-07-22 15:09:38 +08:00
    前后端统一就行(意味着有一个文档来进行维护,类似字典),至于值是什么在编写代码的时候无关紧要,值只有在传输或者存储的时候才会被用到。不同语言的对于枚举这个东西定义还不一样,不过逻辑上来讲枚举通常意义下就是一个有限的集合,这个集合里面定义的每一个枚举单位都是独一无二的,这样就可以借助语言的特性来进行一些约束性的操作。
    bootvue
        4
    bootvue  
       2022-07-22 15:10:06 +08:00
    从几开始关他屁事
    IceBay
        5
    IceBay  
       2022-07-22 15:14:44 +08:00
    但凡写过项目,就知道从几开始关他屁事
    lanlanye
        6
    lanlanye  
       2022-07-22 15:16:20 +08:00   ❤️ 3
    我记得 Uber 的 Golang 风格里提到过建议从 1 开始,理由和你说的一样
    wowawesome
        7
    wowawesome  
       2022-07-22 15:17:20 +08:00
    直接叼他,从几开始关你屁事,看劳资的接口文档用就行了。
    Lin0936
        8
    Lin0936  
       2022-07-22 15:19:55 +08:00   ❤️ 13
    下次给他从 999 开始倒着来
    menc
        9
    menc  
       2022-07-22 15:22:36 +08:00
    scala 的 tuple 类型下标就是从 1 开始的,你可以回一个阴阳怪气,“但凡学过 scala ,也应该知道....”
    menc
        10
    menc  
       2022-07-22 15:24:39 +08:00   ❤️ 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-07-22 15:26:53 +08:00 via Android
    我一般也喜欢从 1 开始,因为 0 是默认值,用 0 当枚举偶尔出错忘了赋值的时候都不容易发现
    HOU
        12
    HOU  
       2022-07-22 15:27:23 +08:00
    叼他完了,你的设计没错,管的真宽
    marcong95
        13
    marcong95  
       2022-07-22 15:29:31 +08:00
    @menc #10 然而你给的链接里 Scale 的下标是 0 开始的,这就十分有趣了
    dqzcwxb
        14
    dqzcwxb  
       2022-07-22 15:30:29 +08:00
    现在你可以把大家提供的资料甩他脸上,美其名曰"技术分享"
    SuperMild
        15
    SuperMild  
       2022-07-22 15:31:37 +08:00 via Android
    提醒:不是数组,是枚举。
    libook
        16
    libook  
       2022-07-22 15:49:19 +08:00
    既然 Lua 默认从 1 开始,你就把 Lua 的文档丢给他,说“但凡多了解几门语言也应该知道不一定都从 0 开始。”

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

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

    c 语言里面某些情况也是默认 0 , 所以推荐从 1 开始
    kera0a
        29
    kera0a  
       2022-07-22 16:16:52 +08:00
    要不是今年行情不好, 我就劝你离职了。
    枚举值从几开始都能斗起来,工作氛围是多差啊
    MuXia
        30
    MuXia  
       2022-07-22 16:23:04 +08:00
    @wangtian2020 #20 看了一圈下来,还是你这个离谱
    456789
        31
    456789  
       2022-07-22 16:26:51 +08:00
    有个领导说我 mq 的 top 设置的太长运行中费内存,我看了他一眼说:你说的对,那有 bug 你来改
    456789
        32
    456789  
       2022-07-22 16:27:07 +08:00
    topic
    bxb100
        33
    bxb100  
       2022-07-22 16:36:46 +08:00
    @wangtian2020 太离谱了,你做的是手柄映射啊
    lakehylia
        34
    lakehylia  
       2022-07-22 16:43:43 +08:00
    我都是 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-07-22 16:55:36 +08:00
    枚举本来就不是啥好玩意,明码标价各个值才方便阅读、日志。
    同意的请点赞给我加分!
    Huelse
        36
    Huelse  
       2022-07-22 16:59:20 +08:00
    我也喜欢从 1 开始,0 的隐含意义太多,文档就算是约定了也还要自查一遍才能理清
    itechnology
        37
    itechnology  
       2022-07-22 17:09:51 +08:00
    讲道理,枚举从几开始关他什么事情,就这点事情他也要阴阳怪气,我建议你赶紧离职或者换个项目组
    NGXDLK
        38
    NGXDLK  
       2022-07-22 17:11:00 +08:00
    枚举从 0 还是 1 开始也能拿出来说?我还从 100 开始呢,这 leader 怕不是傻屌大学毕业的
    pkoukk
        39
    pkoukk  
       2022-07-22 17:17:52 +08:00
    @xz410236056 可以用 iota+1 做初始值
    IvanLi127
        40
    IvanLi127  
       2022-07-22 17:19:56 +08:00
    我认为枚举类型内部的表示方式不应该暴露给外部,交互的时候应该用字面值传递,而不是用整数。
    YouRTBUG
        41
    YouRTBUG  
       2022-07-22 17:42:05 +08:00
    就这也是 leader ?
    molvqingtai
        42
    molvqingtai  
       2022-07-22 17:45:29 +08:00 via Android
    我写前端使用 -1 表示全部🐶
    BeautifulSoap
        43
    BeautifulSoap  
       2022-07-22 17:56:02 +08:00 via Android
    都用枚举了还在乎起始值?直接给他来个 99 起,专治不服
    lihengyu
        44
    lihengyu  
       2022-07-22 17:56:08 +08:00
    我一般 100 ,200 ,300🐶
    catsoul
        45
    catsoul  
       2022-07-22 18:01:12 +08:00
    @BeautifulSoap 雀食,枚举就别跟其他的混了,直接 100 起跳
    Building
        46
    Building  
       2022-07-22 18:01:19 +08:00 via iPhone
    枚举值和属性值绑定,随便
    枚举值和属性值无关,还是随便
    但我喜欢有默认值的时候在 0 位放默认值,没有默认值用 none
    stevefan1999
        47
    stevefan1999  
       2022-07-22 18:07:49 +08:00 via Android
    不要爭論這個問題

    lua 壬震怒(我不是)

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

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

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

    文档: ( X )
    1 ,状态 1
    2 ,状态 2
    buxudashi
        53
    buxudashi  
       2022-07-22 19:34:11 +08:00
    1 就是 1.而 0 就不一定了。有时 false,null,空字符串,empty(),什么乱七八糟的相通。

    所以你是对的。
    elevioux
        54
    elevioux  
       2022-07-22 20:07:31 +08:00 via Android
    php 开发,从 1 开始,理由一样
    xiubin
        55
    xiubin  
       2022-07-22 20:11:11 +08:00
    从 0 开始,0 是无业务意义或者默认的一档,比如 0 可以是:unknow 、none 、default 、normal 。

    iOS 开发( OC 语言)一般无法识别 nil 0 null 的区别
    mengzhuo
        56
    mengzhuo  
       2022-07-22 20:12:02 +08:00
    枚举的话,0 一般是非法(就是防止协议解析失败)
    byzod
        57
    byzod  
       2022-07-22 20:12:06 +08:00
    标准答案:关你卵事,我从 114514 开始
    FrankHB
        58
    FrankHB  
       2022-07-22 20:25:25 +08:00
    下标的问题,只能说历史丈育太多,典都不知道,还用得着举例了: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-07-22 20:42:34 +08:00   ❤️ 1
    如果是 enum 关联到整数,那我还是倾向从 0 开始,0 就是一个默认值。
    lua 那个设计 table 就是从 1 开始的,所以 enum 从 1 开始也算符合他们的习惯。
    其他不少语言 enum 可以不关联到整数,那就不用争了。
    uselessVisitor
        60
    uselessVisitor  
       2022-07-22 21:26:34 +08:00
    想从多少就多少呗,写清楚不就行了。。咋还有这种领导。。
    bojackhorseman
        61
    bojackhorseman  
       2022-07-22 21:49:44 +08:00 via iPhone
    别的不知道,反正我们的 go 后端用 1 表示有,2 表示没有
    Leviathann
        62
    Leviathann  
       2022-07-22 21:55:58 +08:00
    为什么不是直接序列化成字符串
    banricho
        63
    banricho  
       2022-07-22 21:59:36 +08:00
    为啥要让前端知道数字
    接口里看到不是字符串而是一堆数字搭配文档的,是我也要阴阳怪气
    ikaros
        64
    ikaros  
       2022-07-22 22:10:41 +08:00
    有些语言从 0 开始会有问题(golang), 所以从 1 开始准没错
    blankmiss
        65
    blankmiss  
       2022-07-22 22:28:53 +08:00
    @wangtian2020 我靠 这是什么操作
    Helsing
        66
    Helsing  
       2022-07-22 23:08:10 +08:00 via iPhone
    习惯确实是从 0 开始,你从 1 开始的理由没有说服力
    aMR
        67
    aMR  
       2022-07-22 23:54:21 +08:00
    当然是互相妥协一下从 0.5 开始 ε=ε=ε=┏(゜ロ゜;)┛

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

    抛开具体语言,枚举值不仅仅只能用数字表示,难道用字符表示枚举,还得从 A 开始吗?
    zed1018
        72
    zed1018  
       2022-07-23 08:25:36 +08:00
    使用数字作为枚举值 ×
    使用单词作为枚举值 √

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

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

    这样一来,那些没有赋值的枚举们就会直接崩溃,而代码也只需要在入口的地方处理掉这些 0 们,而不是每次写判断的时候脑子里都要带着这个 Invalid 。
    DeWjjj
        92
    DeWjjj  
       2022-07-23 14:16:41 +08:00
    默认 = 0 ,部分特定写 1 。
    文档里面都有,给什么写什么。
    ppllss
        93
    ppllss  
       2022-07-25 09:14:40 +08:00
    从 0 开始
    menc
        94
    menc  
       2022-07-26 10:06:43 +08:00
    @marcong95 数组和 tuple 是两回事
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6007 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 50ms · UTC 02:22 · PVG 10:22 · LAX 18:22 · JFK 21:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.