Go 入门到精通-05-常量与运算符

目录

  • [🟢 基础入门 | Go 入门到精通 2026(五):常量与运算符](#🟢 基础入门 | Go 入门到精通 2026(五):常量与运算符)
    • 开篇
    • [1. 常量 const](#1. 常量 const)
      • [1.1 常量的声明](#1.1 常量的声明)
      • [1.2 批量声明常量](#1.2 批量声明常量)
      • [1.3 无类型常量](#1.3 无类型常量)
      • [1.4 常量的使用限制](#1.4 常量的使用限制)
    • [2. iota 枚举生成器](#2. iota 枚举生成器)
      • [2.1 基本用法](#2.1 基本用法)
      • [2.2 iota 的中断与跳过](#2.2 iota 的中断与跳过)
        • [中断 iota](#中断 iota)
        • [跳过某个值(使用 `_`)](#跳过某个值(使用 _))
      • [2.3 位掩码(Bitmask)](#2.3 位掩码(Bitmask))
      • [2.4 iota 复杂表达式](#2.4 iota 复杂表达式)
      • [2.5 iota 实战:定义 HTTP 状态码分组](#2.5 iota 实战:定义 HTTP 状态码分组)
    • [3. 算术运算符](#3. 算术运算符)
    • [4. 比较运算符](#4. 比较运算符)
    • [5. 逻辑运算符](#5. 逻辑运算符)
    • [6. 位运算符](#6. 位运算符)
    • [7. 赋值运算符](#7. 赋值运算符)
    • [8. 运算符优先级](#8. 运算符优先级)
    • [9. 自增与自减](#9. 自增与自减)
    • [10. 综合实战:权限管理系统](#10. 综合实战:权限管理系统)
    • 小结与互动
    • 参考资料

🟢 基础入门 | Go 入门到精通 2026(五):常量与运算符

📅 更新于 2026年6月 | ✍️ 原创文章,转载请注明出处 | 作者:布朗克168



开篇

上一篇文章我们学习了变量和数据类型,知道了如何存储"可以变化的数据"。但程序中还有一些在整个运行期间都不会改变的值 ------这就是常量

运算符则是操作变量和常量的工具。Go 的运算符设计保持了其一贯的简洁哲学:种类不多,但够用;规则清晰,没有歧义。

🎯 本文重点:✅ 常量与 iota 枚举 ✅ 七类运算符 ✅ 优先级规则 ✅ 自增自减的特殊性


1. 常量 const

1.1 常量的声明

常量使用 const 关键字声明,必须在声明时赋值,且值在编译时就能确定:

go 复制代码
const Pi = 3.14159
const AppName = "GoBlog"
const MaxRetries = 3
const IsDebug = false

// 可以指定类型
const Version string = "1.26.0"
const Port int = 8080

⚠️ 常量和变量的核心区别:

  • 常量用 const,变量用 var:=
  • 常量必须在声明时赋值,且之后不能修改
  • 常量的值必须在编译时就能确定,不能是函数调用的返回值
go 复制代码
// ❌ 编译错误:常量的值必须编译时确定
const Now = time.Now()        // 函数返回值,不行
const Random = rand.Intn(100) // 函数返回值,不行
const Config = readConfig()   // 函数返回值,不行

// ✅ 编译时常量表达式是可以的
const SecondsPerMinute = 60
const SecondsPerHour = SecondsPerMinute * 60   // 3600
const SecondsPerDay = SecondsPerHour * 24      // 86400

1.2 批量声明常量

和变量一样,常量也支持批量声明:

go 复制代码
const (
    StatusOK     = 200
    StatusNotFound = 404
    StatusError  = 500
)

更有趣的是,批量声明结合 iota 可以自动生成递增值------这个后面详讲。

1.3 无类型常量

Go 的常量有一个非常独特的特性:无类型常量(untyped constant)

go 复制代码
const Value = 42  // 没有指定类型,这是一个无类型常量

无类型常量拥有更高的精度更灵活的使用方式

go 复制代码
const BigNumber = 1 << 100  // 天文数字,远超 int64 范围
// 但是没有溢出!因为无类型常量可以"无限大"

// 无类型常量可以赋值给不同类型的小变量(只要不溢出)
var a int = 42          // ✅
var b int8 = 42         // ✅
var c float64 = 42      // ✅
var d complex128 = 42   // ✅

// 有类型常量就不能这样随意
const TypedValue int = 42
var e float64 = TypedValue  // ❌ 编译错误!int 不能直接赋给 float64
var f float64 = float64(TypedValue) // ✅ 需要显式转换

💡 核心区别:无类型常量像是一种"理想数",可以自动适配到需要的具体类型;而有类型常量则遵循严格的类型规则。

1.4 常量的使用限制

go 复制代码
// ❌ 常量不能取地址(常量不在内存中有固定地址)
const Name = "Go"
// ptr := &Name  // 编译错误!

// ❌ 常量不能修改
const X = 10
// X = 20  // 编译错误!

// ✅ 常量可以参与编译时计算的表达式
const (
    A = 10
    B = A * 2      // 20
    C = len("Hi")  // 2,len 作用在字符串常量上是编译时求值
)

2. iota 枚举生成器

iota 是 Go 中最有特色的关键字之一。它是一个常量计数器 ,在 const 块中从 0 开始,每新增一行常量声明,iota 自动加 1。

2.1 基本用法

go 复制代码
const (
    Monday    = iota  // 0
    Tuesday           // 1(隐式沿用上一行的表达式,iota 自增)
    Wednesday         // 2
    Thursday          // 3
    Friday            // 4
    Saturday          // 5
    Sunday            // 6
)

func main() {
    fmt.Println(Monday)     // 0
    fmt.Println(Tuesday)    // 1
    fmt.Println(Sunday)     // 6
}

🔑 关键规则:在 const() 块内,如果一行没有写表达式,就自动沿用上一行的表达式 ,同时 iota 会自动加 1。

自定义起始值
go 复制代码
const (
    _ = iota       // 0(丢弃,用 _ 占位)
    KB = 1 << (10 * iota)  // 1 << 10 = 1024
    MB                       // 1 << 20 = 1048576
    GB                       // 1 << 30 = 1073741824
    TB                       // 1 << 40 = 1099511627776
)

func main() {
    fmt.Printf("KB = %d\n", KB)  // 1024
    fmt.Printf("MB = %d\n", MB)  // 1048576
    fmt.Printf("GB = %d\n", GB)  // 1073741824
    fmt.Printf("TB = %d\n", TB)  // 1099511627776
}

2.2 iota 的中断与跳过

中断 iota
go 复制代码
const (
    A = iota  // 0
    B         // 1
    C = 100   // 100(显式赋值,iota 仍然 +1 但现在值是 100)
    D         // 100(沿用 C 的表达式,不是 iota!)
    E = iota  // 4(重新用 iota,此时 iota 已递增到 4)
)

func main() {
    fmt.Println(A, B, C, D, E)  // 0 1 100 100 4
}
跳过某个值(使用 _
go 复制代码
const (
    Bronze = iota   // 0
    Silver          // 1
    _               // 2(跳过)
    Gold            // 3
    _               // 4(跳过)
    Diamond         // 5
)

func main() {
    fmt.Println(Bronze, Silver, Gold, Diamond)  // 0 1 3 5
}

2.3 位掩码(Bitmask)

位掩码是 iota 最实用的场景之一,广泛用于权限控制、状态标志等:

go 复制代码
const (
    FlagRead    = 1 << iota  // 1 << 0 = 1   (二进制: 0001)
    FlagWrite                // 1 << 1 = 2   (二进制: 0010)
    FlagExecute              // 1 << 2 = 4   (二进制: 0100)
    FlagDelete               // 1 << 3 = 8   (二进制: 1000)
)

func main() {
    // 组合权限:读 + 写 + 执行
    permission := FlagRead | FlagWrite | FlagExecute  // 0001 | 0010 | 0100 = 0111 = 7

    fmt.Printf("权限值: %d, 二进制: %04b\n", permission, permission)
    // 权限值: 7, 二进制: 0111

    // 检查某个权限
    hasRead := permission&FlagRead != 0     // true
    hasDelete := permission&FlagDelete != 0 // false

    fmt.Printf("有读权限: %t\n", hasRead)     // true
    fmt.Printf("有删除权限: %t\n", hasDelete)  // false

    // 添加权限
    permission |= FlagDelete  // 0111 | 1000 = 1111 = 15

    // 移除权限
    permission &^= FlagWrite  // 1111 &^ 0010 = 1101 = 13(移除写权限)
}

2.4 iota 复杂表达式

每个 const 块中的 iota 是独立的,可以在同一行多次引用:

go 复制代码
const (
    // iota 在同一行不会自增,自增发生在每个 const 行之间
    A, B = iota, iota + 1   // A=0, B=1
    C, D                    // C=1, D=2
    E, F                    // E=2, F=3
)

const (
    // 更实用的例子:定义带名称的偏移量
    Offset0 = iota * 10     // 0
    Offset1                 // 10
    Offset2                 // 20
    Offset3                 // 30
)

2.5 iota 实战:定义 HTTP 状态码分组

go 复制代码
const (
    // HTTP 状态码分组
    StatusOK           = 200
    StatusCreated      = 201
    StatusNoContent    = 204

    StatusBadRequest   = 400
    StatusUnauthorized = 401
    StatusForbidden    = 403
    StatusNotFound     = 404

    StatusInternalError = 500
    StatusBadGateway    = 502
)

// 使用 iota 定义状态码类别
const (
    CategoryInfo      = iota + 1  // 1(1xx)
    CategorySuccess               // 2(2xx)
    CategoryRedirect              // 3(3xx)
    CategoryClientError           // 4(4xx)
    CategoryServerError           // 5(5xx)
)

func getCategory(code int) int {
    return code / 100
}

3. 算术运算符

Go 的算术运算符和大多数语言一致:

go 复制代码
a := 10
b := 3

fmt.Println(a + b)   // 13(加)
fmt.Println(a - b)   // 7 (减)
fmt.Println(a * b)   // 30(乘)
fmt.Println(a / b)   // 3 (除:整数除整数 = 整数,截断!)
fmt.Println(a % b)   // 1 (取模/取余)

// 注意:整数除法
fmt.Println(10 / 3)     // 3(不是 3.333!)
fmt.Println(10.0 / 3.0) // 3.3333333333333335

// 自增自减(独立的语句,非运算符------后面详讲)
a++  // a = 11
b--  // b = 2

算术运算的类型要求

go 复制代码
var x int = 10
var y int32 = 20

// fmt.Println(x + y)  // ❌ 编译错误!int 和 int32 是不同的类型
fmt.Println(x + int(y)) // ✅ 显式转换

var m float32 = 3.14
var n float64 = 2.71

// fmt.Println(m + n)  // ❌ 编译错误!float32 和 float64 也是不同类型
fmt.Println(float64(m) + n) // ✅

溢出问题

go 复制代码
var maxUint8 uint8 = 255
maxUint8++              // 溢出!变成 0(wraparound)
fmt.Println(maxUint8)   // 0

var minInt8 int8 = -128
minInt8--               // 溢出!变成 127
fmt.Println(minInt8)    // 127

⚠️ Go 默认不做溢出检查,需要自己注意,或使用 math/big 包进行大数运算。


4. 比较运算符

比较运算符返回 bool 值:

go 复制代码
a, b := 10, 20

fmt.Println(a == b)  // false(等于)
fmt.Println(a != b)  // true (不等于)
fmt.Println(a < b)   // true (小于)
fmt.Println(a <= b)  // true (小于等于)
fmt.Println(a > b)   // false(大于)
fmt.Println(a >= b)  // false(大于等于)

比较规则

go 复制代码
// 同类型比较
fmt.Println(10 == 10)       // true
fmt.Println(3.14 > 3.0)     // true
fmt.Println("abc" == "abc") // true
fmt.Println("abc" < "abd")  // true(字典序比较)
fmt.Println(true != false)  // true

// 不同类型不能比较
// fmt.Println(10 == 10.0)  // ❌ 编译错误!(但无类型常量可以:10 == 10.0 → true)

// 指针比较
var p1, p2 *int
fmt.Println(p1 == p2)  // true(都是 nil)

// 数组比较(元素类型可比较时,数组可比较)
arr1 := [3]int{1, 2, 3}
arr2 := [3]int{1, 2, 3}
arr3 := [3]int{1, 2, 4}
fmt.Println(arr1 == arr2) // true
fmt.Println(arr1 == arr3) // false

// 切片、map、函数不能直接用 == 比较(只能和 nil 比)
// s1 := []int{1, 2, 3}
// s2 := []int{1, 2, 3}
// fmt.Println(s1 == s2)  // ❌ 编译错误!
fmt.Println(s1 == nil)    // ✅

5. 逻辑运算符

go 复制代码
a, b := true, false

fmt.Println(a && b)  // false(逻辑与:两边都为 true 才为 true)
fmt.Println(a || b)  // true (逻辑或:至少一边为 true 就为 true)
fmt.Println(!a)      // false(逻辑非:取反)

// 短路求值
if getUser() != nil && getUser().IsAdmin() {
    // 如果 getUser() 返回 nil,后面的 IsAdmin() 不会执行
    // 避免了空指针问题
}

短路求值演示

go 复制代码
func expensiveCheck() bool {
    fmt.Println("执行了昂贵检查")
    return true
}

func main() {
    // 短路与:第一条件为 false,第二个不会执行
    if false && expensiveCheck() {
        fmt.Println("不会到这里")
    }
    // 输出:(什么也没输出,expensiveCheck 没有被调用)

    // 短路或:第一条件为 true,第二个不会执行
    if true || expensiveCheck() {
        fmt.Println("执行了")
    }
    // 输出:执行了(expensiveCheck 没有被调用)
}

💡 利用短路求值可以写出更高效的代码:把"便宜的"检查放前面,"昂贵的"放后面。


6. 位运算符

位运算符直接操作二进制位,在系统编程、权限控制、性能优化中非常有用。

go 复制代码
a := 0b1100  // 12(二进制 1100)
b := 0b1010  // 10(二进制 1010)

// 按位与:对应位都为 1 才为 1
fmt.Printf("%04b\n", a&b)  // 1000 = 8

// 按位或:对应位有 1 就为 1
fmt.Printf("%04b\n", a|b)  // 1110 = 14

// 按位异或:对应位不同为 1
fmt.Printf("%04b\n", a^b)  // 0110 = 6

// 按位取反(一元运算符):所有位翻转
fmt.Printf("%04b\n", ^a)   // 在 Go 中 ^a 等价于按位取反

// 左移:所有位左移 n 位,低位补 0
fmt.Printf("%04b\n", a<<1) // 11000 = 24

// 右移:所有位右移 n 位,高位补符号位
fmt.Printf("%04b\n", a>>1) // 0110 = 6

// 位清空(AND NOT):清除 b 中为 1 的位
fmt.Printf("%04b\n", a&^b) // 0100 = 4
// 解释:a&^b = a & (^b),先取反 b,再与 a

位运算符速查表

运算符 名称 示例 说明
& 按位与 a & b 对应位都为 1 得 1
` ` 按位或 `a
^ 按位异或 a ^ b 对应位不同得 1
^ 按位取反 ^a 所有位翻转(一元用法的 ^)
&^ 位清空 a &^ b 清除 b 中为 1 的那些位
<< 左移 a << n 左移 n 位,低位补 0
>> 右移 a >> n 右移 n 位,高位补符号位

实用技巧

go 复制代码
// 乘以/除以 2 的幂(通常比乘除法快)
x := 10
fmt.Println(x << 1)  // 20(乘以 2)
fmt.Println(x >> 1)  // 5 (除以 2)
fmt.Println(x << 3)  // 80(乘以 8,即 2³)

// 判断奇偶
n := 7
if n&1 == 0 {
    fmt.Println("偶数")
} else {
    fmt.Println("奇数")  // 输出这个
}

// 交换两个数(不借助临时变量)
a, b := 3, 5
a ^= b
b ^= a
a ^= b
fmt.Println(a, b)  // 5 3

// 取绝对值(不分支)
// 对 32 位整数有效
abs := n ^ (n >> 31) - (n >> 31)

7. 赋值运算符

Go 的赋值运算符是"运算 + 赋值"的简写形式:

go 复制代码
x := 10

x += 5   // x = x + 5  → 15
x -= 3   // x = x - 3  → 12
x *= 2   // x = x * 2  → 24
x /= 4   // x = x / 4  → 6
x %= 4   // x = x % 4  → 2

// 位运算赋值
x &= 3   // x = x & 3
x |= 1   // x = x | 1
x ^= 2   // x = x ^ 2
x &^= 1  // x = x &^ 1
x <<= 2  // x = x << 2
x >>= 1  // x = x >> 1

多重赋值

Go 支持独特的多重赋值,这在交换变量时特别方便:

go 复制代码
// 交换两个变量(不需要临时变量)
a, b := 1, 2
a, b = b, a        // a=2, b=1

// 函数返回多个值
x, err := strconv.Atoi("42")

// 平行赋值
var m, n int
m, n = 10, 20

8. 运算符优先级

Go 的运算符优先级从高到低排列:

优先级 运算符 说明
最高 5 * / % << >> & &^ 乘除、移位、按位与
4 + - ` ^`
3 == != < <= > >= 比较
2 && 逻辑与
最低 1 `

📌 Go 的优先级层次简单明了(只有 5 层),比 C 语言的 17 级简单太多了!但是:

go 复制代码
// ⚠️ 不确定优先级时,加括号!加括号!加括号!
result := (a + b) * c      // 清晰
// result := a + b * c    // 虽然也能算,但不清晰

// 特别注意:位运算符优先级低于比较运算符
if x&0xFF == 0xAB {        // 实际是 x & (0xFF == 0xAB),不是我们想要的!
    // 大部分情况下这不是你的意图
}

// 正确写法
if (x & 0xFF) == 0xAB {    // ✅ 加括号明确意图
}

🔑 黄金法则:不确定优先级就加括号。代码是写给人看的,清晰比简洁重要 100 倍。

结合方向

Go 中所有二元运算符都是左结合的(从左往右计算):

go 复制代码
a := 10 - 5 - 2    // (10 - 5) - 2 = 3
b := 100 / 10 / 2  // (100 / 10) / 2 = 5

9. 自增与自减

Go 的 ++-- 和 C/Java 有一个关键区别

⚠️ Go 中 ++ 和 -- 是语句,不是表达式!

go 复制代码
x := 10

// ✅ 正确:独立的语句
x++
x--

// ❌ 错误:不能作为表达式使用
// y := x++        // 编译错误!syntax error: unexpected ++
// if x++ > 10 {}  // 编译错误!
// fmt.Println(x++) // 编译错误!
// arr[x++]         // 编译错误!

只有后置形式

go 复制代码
// ✅ 只有后置
x++  // 等价于 x = x + 1
x--  // 等价于 x = x - 1

// ❌ Go 中没有前置 ++x 或 --x
// ++x  // 编译错误!
// --x  // 编译错误!

为什么这样设计?

Go 团队认为 ++-- 作为表达式容易产生歧义和难以发现的错误:

go 复制代码
// C 语言中的困惑(Go 中完全避免了这些问题):
// int y = x++ + ++x;  // y 是多少?取决于编译器实现!
// arr[x++] = x;       // x 被递增前后的值?

💡 Go 的做法更清晰:x++ 就是"把 x 加 1",没有其他副作用。


10. 综合实战:权限管理系统

综合运用常量、iota、位运算符,构建一个简单的权限管理系统:

go 复制代码
package main

import (
    "fmt"
    "strings"
)

// ===== 使用 iota + 位掩码定义权限 =====
const (
    PermNone  = 0          // 无权限
    PermRead  = 1 << iota  // 1  << 0 = 1   (读)
    PermWrite              // 1  << 1 = 2   (写)
    PermDelete             // 1  << 2 = 4   (删除)
    PermAdmin              // 1  << 3 = 8   (管理)
    PermOwner              // 1  << 4 = 16  (所有者)
)

// 权限名称映射
var permNames = map[int]string{
    PermRead:   "读",
    PermWrite:  "写",
    PermDelete: "删除",
    PermAdmin:  "管理",
    PermOwner:  "所有者",
}

// ===== 使用 iota 定义角色 =====
const (
    RoleGuest = iota  // 0
    RoleUser           // 1
    RoleEditor         // 2
    RoleAdmin          // 3
)

var roleNames = map[int]string{
    RoleGuest:  "游客",
    RoleUser:   "用户",
    RoleEditor: "编辑",
    RoleAdmin:  "管理员",
}

// 角色默认权限表
var rolePermissions = map[int]int{
    RoleGuest:  PermRead,
    RoleUser:   PermRead | PermWrite,
    RoleEditor: PermRead | PermWrite | PermDelete,
    RoleAdmin:  PermRead | PermWrite | PermDelete | PermAdmin,
}

// ===== 运算符应用 =====

// 检查是否拥有某项权限
func hasPermission(userPerms, perm int) bool {
    return userPerms&perm != 0
}

// 添加权限
func addPermission(userPerms, perm int) int {
    return userPerms | perm
}

// 移除权限
func removePermission(userPerms, perm int) int {
    return userPerms &^ perm
}

// 格式化显示权限
func formatPermissions(perms int) string {
    if perms == 0 {
        return "无"
    }
    var result []string
    // 按位检查
    check := []int{PermRead, PermWrite, PermDelete, PermAdmin, PermOwner}
    for _, p := range check {
        if hasPermission(perms, p) {
            result = append(result, permNames[p])
        }
    }
    return strings.Join(result, " | ")
}

// ===== 主函数 =====
func main() {
    fmt.Println(strings.Repeat("=", 50))
    fmt.Println("🔐 权限管理系统演示")
    fmt.Println(strings.Repeat("=", 50))

    // 1. 基础运算演示
    fmt.Println("\n📐 基础运算符演示:")
    a, b := 15, 4
    fmt.Printf("  %d + %d = %d\n", a, b, a+b)
    fmt.Printf("  %d - %d = %d\n", a, b, a-b)
    fmt.Printf("  %d * %d = %d\n", a, b, a*b)
    fmt.Printf("  %d / %d = %d(整数除法)\n", a, b, a/b)
    fmt.Printf("  %d %% %d = %d\n", a, b, a%b)

    // 2. 位运算演示
    fmt.Println("\n🔢 位运算演示 (a=12, b=10):")
    a, b = 12, 10 // 1100, 1010
    fmt.Printf("  a = %04b (%d), b = %04b (%d)\n", a, a, b, b)
    fmt.Printf("  a & b  = %04b (%d)  # 按位与\n", a&b, a&b)
    fmt.Printf("  a | b  = %04b (%d) # 按位或\n", a|b, a|b)
    fmt.Printf("  a ^ b  = %04b (%d)  # 按位异或\n", a^b, a^b)
    fmt.Printf("  a &^ b = %04b (%d)  # 位清空\n", a&^b, a&^b)
    fmt.Printf("  a << 1 = %05b (%d) # 左移\n", a<<1, a<<1)
    fmt.Printf("  a >> 1 = %04b (%d)  # 右移\n", a>>1, a>>1)

    // 3. 逻辑运算演示
    fmt.Println("\n🧠 逻辑运算符演示:")
    fmt.Printf("  true && false = %t\n", true && false)
    fmt.Printf("  true || false = %t\n", true || false)
    fmt.Printf("  !true = %t\n", !true)

    // 4. 权限系统演示
    fmt.Println("\n" + strings.Repeat("=", 50))
    fmt.Println("👥 角色权限演示")
    fmt.Println(strings.Repeat("=", 50))

    for role := RoleGuest; role <= RoleAdmin; role++ {
        perms := rolePermissions[role]
        fmt.Printf("\n  %s(角色%d):\n", roleNames[role], role)
        fmt.Printf("    权限值: %d (%05b)\n", perms, perms)
        fmt.Printf("    权限: %s\n", formatPermissions(perms))

        // 检查具体权限
        fmt.Printf("    能读? %t\n", hasPermission(perms, PermRead))
        fmt.Printf("    能写? %t\n", hasPermission(perms, PermWrite))
        fmt.Printf("    能删? %t\n", hasPermission(perms, PermDelete))
    }

    // 5. 动态修改权限
    fmt.Println("\n" + strings.Repeat("=", 50))
    fmt.Println("🔧 动态修改权限演示")
    fmt.Println(strings.Repeat("=", 50))

    userPerms := PermRead | PermWrite
    fmt.Printf("  初始权限: %s\n", formatPermissions(userPerms))

    userPerms = addPermission(userPerms, PermDelete)
    fmt.Printf("  授予删除: %s\n", formatPermissions(userPerms))

    userPerms = removePermission(userPerms, PermWrite)
    fmt.Printf("  撤销写入: %s\n", formatPermissions(userPerms))

    // 6. 自增自减演示
    fmt.Println("\n📈 自增自减演示:")
    counter := 0
    fmt.Printf("  初始: %d\n", counter)
    counter++
    fmt.Printf("  counter++: %d\n", counter)
    counter += 5
    fmt.Printf("  counter += 5: %d\n", counter)
    counter--
    fmt.Printf("  counter--: %d\n", counter)

    fmt.Println("\n" + strings.Repeat("=", 50))
}

运行输出(关键部分):

复制代码
🔐 权限管理系统演示
==================================================

📐 基础运算符演示:
  15 + 4 = 19
  15 - 4 = 11
  15 * 4 = 60
  15 / 4 = 3(整数除法)
  15 % 4 = 3

👥 角色权限演示
==================================================

  用户(角色1):
    权限值: 3 (00011)
    权限: 读 | 写
    能读? true
    能写? true
    能删? false

  管理员(角色3):
    权限值: 15 (01111)
    权限: 读 | 写 | 删除 | 管理
    能读? true
    能写? true
    能删? true

小结与互动

📝 本文要点回顾

  1. 常量const 声明,值必须在编译时确定,支持无类型常量
  2. iota 是常量计数器,配合位掩码可实现优雅的权限控制
  3. 七类运算符:算术、比较、逻辑、位、赋值、自增自减,以及它们的优先级
  4. Go 的 ++/--语句 而非表达式 ,且只有后置形式------这个设计和 C/Java 完全不同
  5. 位运算符看似冷门,但在权限系统、协议解析、性能优化中是利器
  6. 不确定优先级就加括号------代码清晰比聪明重要

互动问题

  • 你之前用过的语言中,常量和 Go 的有什么不同?
  • iota + 位掩码的组合你学会了吗?试着用位掩码定义自己的权限系统!
  • 你对 Go 把 ++/-- 设计为语句而非表达式怎么看?是更清晰还是更麻烦?

欢迎在评论区分享你的代码和想法!👇


参考资料


🚀 下一篇预告【Go 入门到精通 2026(六):流程控制------if、for、switch】,带你掌握 Go 中唯一的循环关键字 for 和优雅的 switch


本文由 布朗克168 原创发布,如需转载请联系作者并注明出处。