Files
cs-note/hzh/GolangStar/Go语言基础/Go语言常量.md
T

3.6 KiB
Raw Blame History

tags, create time
tags create time
go
golang
go基础语法
常量
2026-06-07 15:00

Go 语言常量

概述

常量是编译期确定的不可变值。本文介绍常量的声明方式、iota 枚举技巧,以及常量与变量的关键区别。

正文

常量 vs 变量:本质区别是什么?

常量在编译期就确定了值,之后不可修改。 这意味着编译器可以做更多优化,比如内联替换、死代码消除等。

const MaxSize = 1024       // 编译期确定,不可更改
// MaxSize = 2048          // ❌ 编译错误:cannot assign to MaxSize

var BufferSize = 1024      // 运行时可变
BufferSize = 2048          // ✅ 合法

[!note] 📝 常量类型限制 只能是布尔型、数字型(整数/浮点/复数)、字符串。不能是 slice、map、struct 等复杂类型。

声明方式

const name type = value    // 显式类型
const name = value         // 类型推断(更常用)

// 多常量一行声明
const a, b = "hello", "world"

iota:Go 的枚举神器

iota 是 Go 最优雅的枚举机制之一——它是 const 块内的行索引,从 0 开始,每行自动 +1。

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

[!tip] 💡 省略写法 同一 const 块内,如果后续行的值和上一行一样(都是 iota),可以省略右侧表达式:

const (
    Sunday = iota  // 0
    Monday         // 1  ← 自动继承 iota
    Tuesday        // 2
)

iota 的高级用法

当某行出现了非 iota 的独立值后,iota 继续计数,但其他常量需要重新指定表达式:

const (
    a = iota   // 0
    b          // 1
    c          // 2
    d = "ha"   // "ha" — 独立值,iota 变成 3
    e          // "ha" — 继承上一行的值,iota 变成 4
    f = 100    // 100 — 独立值,iota 变成 5
    g          // 100 — 继承,iota 变成 6
    h = iota   // 6 — 恢复计数
    i          // 7
)

位运算枚举

结合位移操作,iota 可以优雅地生成幂次值:

const (
    _  = iota              // 0,用 _ 丢弃
    KB = 1 << (10 * iota)  // 1 << 0 = 1(通常不用)
    MB                       // 1 << 10 = 1024
    GB                       // 1 << 20 = 1048576
    TB                       // 1 << 30 = 1073741824
)

[!question] ❓ 思考 上面这段代码中,KB、MB、GB 的值分别是多少?为什么 _ 那行很重要?

常量可以用在编译期函数中

len()、cap()、unsafe.Sizeof() 等在常量上下文中是编译期求值的:

const s = "abc"
const n = len(s)        // n == 3,编译期确定
const sz = unsafe.Sizeof(s)  // sz == 16(string struct 大小)

[!info] ℹ️ 为什么 sizeof("abc") 是 16? Go 的 string 底层是一个结构体:{ptr *byte, len int},两个字段各占 8 字节(64 位平台),所以 unsafe.Sizeof(string) 恒为 16。它不包含字符串的实际内容,只包含指向内容的指针和长度。

常量分组示例(枚举最佳实践)

type StatusCode int

const (
    OK       StatusCode = 200
    NotFound StatusCode = 404
    ServerError StatusCode = 500
)

给枚举值绑定自定义类型(如 StatusCode)可以提供类型安全——不同枚举类型之间不能直接比较。

[!warning] ⚠️ 常见陷阱 不带类型的裸 const 会隐式转换为 int。如果需要类型安全,务必显式声明类型或先定义枚举类型。