go 1.13+ 原生支持 0b、0o、0x 整数字面量前缀,仅用于源码标识,编译后与十进制等价;0o 替代旧八进制 0 开头写法以避免歧义,大小写敏感(0xff 非法,0xff 合法),不支持浮点或表达式中使用。

Go 里 0b、0o、0x 是字面量前缀,不是运算符或函数
Go 从 1.13 开始原生支持二进制(0b)、八进制(0o)和十六进制(0x)整数字面量。它们只在源码中起标识作用,编译后和十进制写法完全等价,不产生额外开销。
常见错误是把 0b 当成宏或函数调用,比如写成 0b(1010) 或 int(0b1010) —— 这会直接报错:syntax error: unexpected (。字面量必须是常量形式,不能带括号或参与表达式中间计算。
-
0b1010表示十进制10,仅限整数类型(int、uint8等),不支持浮点或负数前缀(-0b1010合法,但-是一元减号,不是字面量一部分) -
0o755表示八进制755→ 十进制493;注意旧写法0755(无o)在 Go 1.13+ 已被弃用,编译会警告:octal literal prefix 0 is deprecated -
0xFF和0xff都合法,大小写不敏感;但0XFF不行(必须小写x)
为什么 0o 而不是 0 直接开头?避免和十进制混淆
Go 明确废除以 0 开头的八进制写法(如 0755),是因为它和十进制 0123 极易混淆,且历史 C 风格容易引发误读。引入 0o 是为了显式、无歧义。
实际场景中,权限掩码、位标记、硬件寄存器配置常用八进制或十六进制,比如文件权限 0o644 比 420 更直观体现“所有者可读写、组可读、其他可读”的结构。
立即学习“go语言免费学习笔记(深入)”;
- 旧代码迁移时,
go fix可自动将0755替换为0o755,但需人工确认上下文是否真为八进制(有些0开头只是习惯性补零) -
0b在嵌入式或协议解析中高频出现,例如标志位:const flagAck = 0b00000001,比1更易看出位位置 - 十六进制仍是最通用的,尤其与内存地址、颜色值、哈希摘要交互时,
0xFF0000比16711680可读性强得多
字符串转进制字面量?Go 没有内置解析函数,得用 strconv.ParseInt
字面量前缀只存在于源码,运行时无法“识别”字符串里的 "0x" 并自动转成整数。想把用户输入的 "0xFF" 或 "0b1100" 转成数值,必须手动处理前缀再调用解析函数。
直接传 "0xFF" 给 strconv.ParseInt 会失败,因为该函数不认前缀,只接受纯数字字符(按指定进制解释)。错误现象是返回 strconv.ParseInt: parsing "0xFF": invalid syntax。
- 先用
strings.TrimPrefix去掉前缀:strconv.ParseInt(strings.TrimPrefix(s, "0x"), 16, 64) - 对
"0b"和"0o"同理,注意八进制要传8,二进制传2 - 别漏掉错误检查:解析可能返回
err != nil,尤其是输入含非法字符(如"0xGG")或超出整数范围时
跨平台兼容性没问题,但老版本 Go(
如果项目需支持 Go 1.12 或更早,所有 0b/0o 字面量都会导致 syntax error: illegal octal digit 或类似报错。这不是运行时问题,而是语法层面不识别。
没有运行时降级方案——字面量是编译期概念。要么升级 Go 版本,要么改用十进制或 math/bits 等库辅助生成,但后者无法替代源码可读性。
- CI 流水线里务必检查 Go 版本,尤其使用 GitHub Actions 时默认可能拉取旧版
setup-go - 第三方库若用了
0o前缀,而你的项目锁定了旧 Go 版本,就会卡在构建阶段,错误信息很直接,但初学者容易误以为是自己代码问题 - VS Code 的 Go 插件(gopls)对新字面量支持良好,但老旧编辑器可能高亮异常或跳转失败,属于工具链适配问题,不影响编译










