用 iota 写一个类型安全的文件权限常量组

Go中定义文件权限常量应使用自定义类型FileMode封装iota,显式声明权限位(如OwnerRead=1

在 Go 中,用 iota 定义文件权限常量时,需兼顾位运算语义和类型安全——推荐使用自定义整数类型(如 FileMode)封装,并让常量显式属于该类型。

定义类型安全的权限类型

避免直接用 intuint32,而是声明专属类型,确保编译期类型检查:

type FileMode uint32

用 iota 枚举标准 Unix 权限位

每个常量代表一个独立的权限位(非连续数值),便于按位组合(如 OwnerRead | GroupWrite):

const (
    OwnerRead  FileMode = 1 << (9 - 1) // 0400
    OwnerWrite FileMode = 1 << (9 - 2) // 0200
    OwnerExec  FileMode = 1 << (9 - 3) // 0100
    GroupRead  FileMode = 1 << (9 - 4) // 0040
    GroupWrite FileMode = 1 << (9 - 5) // 0020
    GroupExec  FileMode = 1 << (9 - 6) // 0010
    OtherRead  FileMode = 1 << (9 - 7) // 0004
    OtherWrite FileMode = 1 << (9 - 8) // 0002
    OtherExec  FileMode = 1 << (9 - 9) // 0001
)

补充常用组合常量(保持类型一致)

组合值也必须是 FileMode 类型,

防止混入裸整数:

const (
    PermRead   FileMode = OwnerRead | GroupRead | OtherRead   // 0444
    PermWrite  FileMode = OwnerWrite | GroupWrite | OtherWrite // 0222
    PermExec   FileMode = OwnerExec | GroupExec | OtherExec     // 0111
    PermRWX    FileMode = PermRead | PermWrite | PermExec       // 0777
    PermRW     FileMode = PermRead | PermWrite                  // 0666
)

使用示例与类型安全验证

这样定义后,编译器会拒绝非法赋值,例如:

var m FileMode = OwnerRead | GroupWrite // ✅ 正确:同类型按位或
var n int = OwnerRead                    // ❌ 编译错误:不能把 FileMode 赋给 int
os.Chmod("file", OwnerRead|OwnerWrite)  // ✅ 传入 FileMode,类型安全