如何使用位在 Kotlin 中存储配置?

How to use a bit to store a config in Kotlin?

例如将config1-8存入config

var config1 = false
var config2 = false
var config3 = false
var config4 = false
var config5 = false
var config6 = false
var config7 = false
var config8 = false
var config = 0

如果配置是

var config1 = false
var config2 = false
var config3 = false
var config4 = false
var config5 = false
var config6 = false
var config7 = false
var config8 = true

则配置为1

如果配置是

var config1 = false
var config2 = false
var config3 = false
var config4 = false
var config5 = false
var config6 = false
var config7 = true
var config8 = false

则配置为2

如果配置是

var config1 = false
var config2 = false
var config3 = false
var config4 = false
var config5 = false
var config6 = false
var config7 = true
var config8 = true

那么配置是3

然后如何检查整数中的每个配置值?如果config是3,怎么知道config 7和8是真的?

对于位计算,您需要手动将位定义为 2 的幂:

const val CONFIG8 = 1
const val CONFIG7 = 2
const val CONFIG6 = 4
...

然后您可以使用 or 运算符设置配置:

config = 0
config = config or CONFIG8 // = 1
config = config or CONFIG7 // = 3

要读取设置的配置,您需要使用 and 运算符

config and CONFIG8 != 0 // true if 1 or 3 ...
config and CONFIG7 != 0 // true if 2 or 3 ...

要以 int 形式读写布尔值,只需使用二进制掩码:

var config1 = true
var config2 = true
var config3 = false
var config4 = false
var config5 = false
var config6 = true
var config7 = true
var config8 = false


fun main(args : Array<String>) {
    var config = 0
    if(config1){ config = config or 0b10000000}
    if(config2){ config = config or 0b1000000}
    if(config3){ config = config or 0b100000}
    if(config4){ config = config or 0b10000}
    if(config5){ config = config or 0b1000}
    if(config6){ config = config or 0b100}
    if(config7){ config = config or 0b10}
    if(config8){ config = config or 0b1}

    println(config and 0b10000000 > 0)
    println(config and 0b1000000 > 0)
    println(config and 0b100000 > 0)
    println(config and 0b10000 > 0)
    println(config and 0b1000 > 0)
    println(config and 0b100 > 0)
    println(config and 0b10 > 0)
    println(config and 0b1 > 0)
}

输出将是

true
true
false
false
false
true
true
false

您所描述的是 bitvector 和 Java(以及扩展 Kotlin)针对此问题有一个内置的解决方案,EnumSet .示例:

object Demo {

    @JvmStatic
    fun main(args: Array<String>) {


        val configs: EnumSet<Config> = EnumSet.of(ONE, THREE, FIVE)


        println(configs.joinToString())
        // ONE, THREE, FIVE

    }

    enum class Config {
        ONE,
        TWO,
        THREE,
        FOUR,
        FIVE
    }

}

EnumSet 将在内部使用位向量,但您不需要手动处理它。

文档中的相关部分:

A specialized Set implementation for use with enum types. All of the elements in an enum set must come from a single enum type that is specified, explicitly or implicitly, when the set is created. Enum sets are represented internally as bit vectors. This representation is extremely compact and efficient. The space and time performance of this class should be good enough to allow its use as a high-quality, typesafe alternative to traditional int-based "bit flags." Even bulk operations (such as containsAll and retainAll) should run very quickly if their argument is also an enum set.