我有这个enum
:
enum class Types(val value: Int) {
FOO(1)
BAR(2)
FOO_BAR(3)
}
如何使用enum
创建该Int
的实例?
我试图做这样的事情:
val type = Types.valueOf(1)
我得到了错误:
整数文字不符合预期的字符串类型
答案 0 :(得分:8)
如果仅使用整数值来维护顺序(需要访问正确的值),则不需要任何额外的代码。您可以使用内置值ordinal。序数表示值在枚举声明中的位置。
这里是一个例子:
enum class Types {
FOO, //Types.FOO.ordinal == 0 also position == 0
BAR, //Types.BAR.ordinal == 1 also position == 1
FOO_BAR //Types.FOO_BAR.ordinal == 2 also position == 2
}
您只需调用以下即可访问序数值:
Types.FOO.ordinal
要获取正确的枚举值,您只需调用:
Types.values()[0] //Returns FOO
Types.values()[1] //Returns BAR
Types.values()[2] //Returns FOO_BAR
Types.values()按声明顺序返回枚举值。
摘要:
Types.values(Types.FOO.ordinal) == Types.FOO //This is true
如果整数值不匹配顺序(int_value!= enum.ordinal),或者您使用的是其他类型(string,float ...),那么您就需要迭代并比较自定义值,如前所述该线程。
答案 1 :(得分:5)
Enum#valueOf
is based on name。这意味着要使用它,您需要使用valueof("FOO")
。 valueof
方法还采用了一个String,它解释了该错误。字符串不是整数。类型很重要。我之所以也提到它的原因是,所以您知道这不是您要寻找的方法。
如果要基于int值获取一个值,则需要定义自己的函数。您可以使用values()
获取枚举中的值,在这种情况下,该值将返回Array<Types>
。您可以使用firstOrNull
作为一种安全的方法,如果您希望使用例外而不是null,则可以使用first
。
因此添加一个伴随对象(相对于枚举是静态的,因此可以在Types.getByValue(1234)
上调用Types.COMPANION.getByValue(1234)
(从Java来的Types.FOO.getByValue(1234)
)。
companion object {
private val values = values();
fun getByValue(value: Int) = values.firstOrNull { it.value == value }
}
values()
每次被调用时都会返回一个新数组,这意味着您应该在本地缓存该数组,以避免每次调用getByValue
时都重新创建一个数组。如果在调用该方法时调用values()
,则可能会反复创建它(取决于实际调用的次数),这会浪费内存。
如果您要执行此操作,则还可以扩展该功能并根据多个参数进行检查。这些类型的函数不仅限于一个参数。
该函数的命名完全取决于您。不必是getByValue
。
答案 2 :(得分:2)
enum class Types(val value: Int) {
FOO(1),
BAR(2),
FOO_BAR(3);
companion object {
fun fromInt(value: Int) = Types.values().first { it.value == value }
}
}
您可能要为该范围添加安全检查并返回null。
答案 3 :(得分:0)
一种幼稚的方式可以是:
enum class Types(val value: Int) {
FOO(1),
BAR(2),
FOO_BAR(3);
companion object {
fun valueOf(value: Int) = Types.values().find { it.value == value }
}
}
然后您可以使用
var bar = Types.valueOf(2)
答案 4 :(得分:0)
这实际上取决于您实际想要做什么。
Types.FOO
@JsonValue
)value
属性)获取枚举值,那么恐怕您将必须实现自己的转换方法,如@Zoe所指出的那样。实现此自定义转换的一种方法是使用转换方法添加一个伴随对象:
enum class Types(val value: Int) {
FOO(1),
BAR(2),
FOO_BAR(3);
companion object {
private val types = values().associate { it.value to it }
fun findByValue(value: Int) = types[value]
}
}
Kotlin中的伴侣对象旨在包含属于该类但不与任何实例绑定的成员(例如Java的static
成员)。
在那里实现该方法,您可以通过调用以下方法来访问值:
var bar = Types.findByValue(2)
答案 5 :(得分:0)
我会提前构建“反向”图。可能不是很大的改进,但是代码也不多。
enum class Test(val value: Int) {
A(1),
B(2);
companion object {
val reverseValues: Map<Int, Test> = values().associate { it.value to it }
fun valueFrom(i: Int): Test = reverseValues[i]!!
}
}
编辑:根据@hotkey的建议,map
... toMap()
更改为associate
。
答案 6 :(得分:0)
尝试一下...
companion object{
fun FromInt(v:Int):Type{
return Type::class.java.constructors[0].newInstance(v) as Type
}
}
答案 7 :(得分:0)
对于那些想要避免为每种类型声明fromInt(...)
的人,请使用class EnumHelper private constructor() {
companion object {
inline fun <reified E : Enum<E>> fromInt(value: Int): E {
return enumValues<E>().first { it.toString().toInt() == value }
}
}
}
,这是一种方法:
Helper类:
enum class FancyEnum(val value: Int){
First(0),
Second(1);
override fun toString(): String = value.toString()
}
枚举示例:
...
fun getPosition(): FancyEnum{
return EnumHelper.fromInt(aGoodIntValue)
}
...
用法:
...
val fancy = EnumHelper.fromInt<FancyEnum>(aGoodIntValue)
val fancyTwo : FancyEnum = EnumHelper.fromInt(aGoodIntValue)
...
或
{{ foo[:1]|lower ~ foo[1:] }}