引入

有些数据在程序运行期间不应该被改变,比如圆周率、状态码、配置上限值。用变量存这些值,万一被误改就麻烦了。常量就是专门用来保存不希望被重新赋值的数据,编译时就确定,运行时不可变。

正文

定义

定义

常量是在编译时就确定值、运行期间不可修改的数据。Go 用 const 关键字声明常量,支持 iota 来自动生成一组递增的枚举值。

语法

// 单个常量
const name = "Tom"
 
// 指定类型
const pi float64 = 3.14159
 
// 常量组
const (
    StatusActive   = 0
    StatusInactive = 1
    StatusBanned   = 2
)

例子

基本常量

const appName = "MyApp"
const version = "1.0.0"
const maxRetries = 3
 
fmt.Println(appName, version, maxRetries)

常量声明后不能重新赋值,否则编译报错:

const x = 10
// x = 20  // 编译错误:cannot assign to x

iota 枚举

iota 是 Go 里生成自增常量的特殊标识符,从 0 开始,每行加 1

const (
    Sunday    = iota  // 0
    Monday            // 1
    Tuesday           // 2
    Wednesday         // 3
    Thursday          // 4
    Friday            // 5
    Saturday          // 6
)

每个 const () 块里 iota0 重新开始。

iota 配合位移

const (
    Read    = 1 << iota  // 1  (二进制 001)
    Write                // 2  (二进制 010)
    Execute              // 4  (二进制 100)
)

这种写法常用来表示位标志,一个整数可以组合多个权限:

perm := Read | Write  // 3 (二进制 011)

跳过 iota 值

const (
    A = iota  // 0
    _         // 1(跳过)
    B         // 2
    C         // 3
)

_ 可以跳过不需要的值。

常量表达式

const (
    KB = 1024
    MB = KB * 1024
    GB = MB * 1024
)
 
fmt.Println(GB)  // 1073741824

常量之间可以互相引用,编译时直接计算好,运行时没有额外开销。

常见写法

写法说明
const x = 10单个常量,类型推断
const x int = 10单个常量,指定类型
const ( … )常量组,批量声明
iota从 0 开始自增
1 << iota位运算枚举
_ 跳过值在 iota 中跳过某个位置

特点

  • 常量值在编译时确定,不能是运行时计算的结果
  • 常量不能:= 声明
  • iota 只在 const () 块内有效,每个块从 0 重新开始
  • Go 没有 enum 关键字,用 const + iota 实现枚举效果
  • 未类型化的常量(untyped constant)可以在不同类型间灵活使用
  • 常量组里可以省略后续行的类型和表达式,编译器会自动沿用上一行的模式
const (
    a = 100      // 100
    b            // 100(沿用上一行)
    c = iota     // 2(iota 在这个块里是第 3 个,从 0 算)
    d            // 3
)

理解

常量的本质是编译时替换,不是运行时的内存地址。Go 的常量系统比其他语言多了 iota 这个工具,写枚举特别方便。const + iota 的组合是 Go 里替代 enum 的标准做法,用熟了以后定义状态码、权限位都很顺手。

引出

常量和变量都搞清楚了,接下来看看怎么对它们做运算。Go 运算符 涵盖了算术、比较、逻辑、位运算这些基本操作。