如何使用位在 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

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

要将布尔值读写为 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

对于位计算,您需要手动将位定义为 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 ...

你描述的是一个位向量,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将在内部使用位向量,但您无需手动弄乱它。

文档中的相关部分:

用于枚举类型的专用 Set 实现。枚举集中的所有元素都必须来自创建枚举集时显式或隐式指定的单个枚举类型。枚举集在内部表示为位向量。这种表示非常紧凑和高效。此类的空间和时间性能应该足够好,以允许将其用作传统的基于 int 的"位标志"的高质量、类型安全的替代方案。即使是批量操作(如 containsAll 和 retainAll(,如果它们的参数也是枚举集,也应该运行得非常快。

最新更新