Go iota + 位运算 做出漂亮的权限位掩码常量

权限掩码用Go的iota配合位运算定义,简洁类型安全且直观;需手动设iota起始值为1以生成1、2、4、8…幂次序列。

用 Go 的 iota 配合位运算定义权限掩码,既简洁又类型安全,还能让代码一眼看出权限组合关系。

用 iota 从 1 开始生成 2 的幂次

默认 iota 从 0 开始,但权限位需要 1, 2, 4, 8...,所以手动重置起始值:

const (
    Read  = 1 << iota // 1 << 0 = 1
    Write             // 1 << 1 = 2
    Delete            // 1 << 2 = 4
    Admin             // 1 << 3 = 8
)

这样每个常量天然互斥,且支持按位或组合(如 Read | Write)。

分组 + 注释增强可读性

实际项目中权限常分维度(如资源、操作、范围),可用空行和注释分组,iota 在每个 const 块内独立计数:

const (
    // 资源权限
    PermUser   = 1 << iota // 1
    PermOrder              // 2
    PermProduct            // 4

    // 操作权限
    PermCreate             // 8(iota 从 3 开始,1<<3)
    PermUpdate             // 16
    PermDelete             // 32

    // 系统级权限
    PermLogin              // 64(iota = 6)
    PermAdmin              // 128
)

注意:不同分组间数值不重叠,靠位移位置自然隔离,避免手动写数字出错。

定义常用组合权限常量

高频组合直接封装成新常量,提升语义清晰度:

const (
    PermReadUser    = PermUser | PermRead
    PermReadWrite   = PermReadUser | PermUpdate
    PermFullUser    = PermUser | P

ermCreate | PermUpdate | PermDelete PermSuperAdmin = PermAdmin | PermLogin | PermFullUser )

这些组合仍为整型常量,参与位运算完全兼容,调用方无需关心底层位结构。

校验权限的推荐写法

检查某权限是否包含在权限集中,用按位与(&)判断:

  • 正确if userPerms&PermWrite != 0 { ... }
  • 错误if userPerms == PermWrite { ... }(忽略组合权限)
  • 批量校验可写成:if userPerms&(PermRead|PermWrite) == (PermRead|PermWrite) { ... }

搭配 Go 1.21+ 的 bits.OnesCount 还能统计开启的权限数量,便于调试。