在 Go 中使用位掩码(使用 iota 进行 Go 枚举)

bud*_*dge 3 go

有点卡住了。

我正在尝试弄清楚如何使用 go 枚举从 const 获取位掩码值。例如,如果密钥为 5,即 0101 位,则将是狗和鱼。获取位值(1、2、4、8、16、32、64 等)以便我可以选择字符串值并返回动物集的最简单方法是什么?

type Key int

const (
    Dog Key = 1 << iota
    Cat
    Fish
    Horse
    Snake
    Rabbit
    Lion
    Rino
    Hedgehog
)
Run Code Online (Sandbox Code Playgroud)

一直在阅读,但我无法解决这个问题。

Cer*_*món 5

Declare a slice of strings where the strings correspond to the constant names:

var animalNames = []string{
    "Dog",
    "Cat",
    "Fish",
    "Horse",
    "Snake",
    "Rabbit",
    "Lion",
    "Rino",
    "Hedgehog",
}
Run Code Online (Sandbox Code Playgroud)

To get the names for the bits, loop through the names. If the corresponding bit is set, add the name to the result:

func Names(k Key) []string {
    var result []string
    for i := 0; i < len(animalNames); i++ {
        if k&(1<<uint(i)) != 0 {
            result = append(result, animalNames[i])
        }
    }
    return result
}
Run Code Online (Sandbox Code Playgroud)

Run it on the playground.

If you change the the constants to be bit indexes instead of bit values, then you can use the stringer utility to create a func (k Key) String() string. Here's the code for this change:

type Key uint

const (
    Dog Key = iota
    Cat
    Fish
    Horse
    Snake
    Rabbit
    Lion
    Rino
    Hedgehog
)

//go:generate stringer -type=Key

func Names(k Key) []string {
    var result []string
    for animal := Dog; animal <= Hedgehog; animal++ {
        if k&(1<<animal) != 0 {
            result = append(result, animal.String())
        }
    }
    return result
}
Run Code Online (Sandbox Code Playgroud)