kotlin - 从 Kotlin 中的位掩码获取枚举列表
问题描述
我在数据库实体中有一个枚举类SettingsVisibility
,我将其转换为位掩码以存储在数据库中。我正在尝试将转换反转为位掩码,并获取枚举列表作为返回值。因此,如果我有一个带有 values 的枚举ONE(1), TWO(2), FOUR(4)
,那么它将存储为Enum(7)
. 我想把7
它转换成{ONE, TWO, FOUR}
.
我的代码如下。我有SettingsVisibility
存储在数据库中的整数值的枚举。当我尝试从数据库中检索时,Objectbox
将使用给定PropertyConvertor
的数据来编组/解组数据。当我想要时convertToEntityProperty
,它应该返回一个仅包含已保存枚举的列表,但目前它返回一个所有枚举的列表。我可以通过 a databaseValue
of 12
,它会返回所有枚举,而不仅仅是 2(位置和付款)。
我认为问题在于它的使用,enumClass.enumConstants
因为它获取了所有值,但是过滤器对此不起作用,所以我被卡住了。
@Entity
data class Settings(
@Id override var id: Long = 0,
@Convert(converter = DocumentVisibilityConverter::class, dbType = Int::class)
val showItems: List<SettingsVisibility>
) : Identifiable<Long> {
lateinit var organisation: ToOne<Organisation>
constructor() : this(
showItems = emptyList(),
)
enum class SettingsVisibility(override val bit: Int) : Flags {
USERS(1),
FINANCE(2),
LOCATION(4),
PAYMENTS(8),
MESSAGES(16),
ERRORS(32),
CANCELLATIONS(64)
}
internal class DocumentVisibilityConverter
: BoxConverters.EnumFlagConverter<SettingsVisibility>(SettingsVisibility::class.java)
}
例如,如果我存储前 3 个,则数据库值为 7 (1+2+4)。
数据库是ObjectBox
,这里是属性转换器:
abstract class EnumFlagConverter<E>(private val enumClass: Class<E>) : PropertyConverter<List<E>, Int> where E : Enum<E>, E : Flags {
override fun convertToDatabaseValue(entityProperty: List<E>?): Int? {
return entityProperty?.toBitMask()?.value
}
override fun convertToEntityProperty(databaseValue: Int?): List<E>? {
return databaseValue?.let(::BitMask)?.enabledValues(enumClass)
}
}
class BitMask(val value: Int)
interface Flags {
val bit: Int
fun toBitMask() = BitMask(bit)
fun <T> BitMask.enabledValues(enumClass: Class<T>): List<T>? where T : Enum<T>, T : Flags? {
return enumClass.enumConstants?.filter(::hasFlag)
}
infix fun <T : Flags?> BitMask.hasFlag(flag: T): Boolean {
if (value == 0 || (value > 0 && flag?.bit == 0)) {
return false
}
return true
}
也许其中的逻辑hasFlag
是错误的,因为我认为如果它不是 0,它只会获取每个枚举。
解决方案
答案是将 , 替换return true
为:
if (flag?.bit?.toByte() == null) {
return false
}
return (this.value.toByte().and(flag.bit.toByte()) == flag.bit.toByte())
这基本上是:bit & mask == bit
推荐阅读
- dafny - dafny 不变量如何处理数据类型
- python - 在 Python3 中使用带有种子值的 itertools.product
- python - 硒没有正确找到元素
- javascript - 如何生成多组 2 个元素的有序组合
- c++ - 将嵌套类型层次结构展平为 std::function 的线性类型序列
- c# - 'Random' 是 'UnityEngine.Random' 和 'System.Random' 错误 Unity 3D C# 之间的歧义引用
- javascript - 前三件免费?
- sql-server - 创建事务日志时无法将参数值从 SqlGuid 转换为字符串。(System.Data)
- node.js - 如何从 google-chat webhook 获取响应数据?
- python-3.x - 将羽毛文件存储到 SQL blob