我有这个enum:
enum class Types(val value: Int) {
FOO(1)
BAR(2)
FOO_BAR(3)
}
Run Code Online (Sandbox Code Playgroud)
如何enum使用创建一个实例Int?
我试图做这样的事情:
val type = Types.valueOf(1)
Run Code Online (Sandbox Code Playgroud)
我得到错误:
整数文字不符合预期的字符串类型
Fra*_*esc 48
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 }
}
}
Run Code Online (Sandbox Code Playgroud)
您可能希望为范围添加安全检查并返回 null。
Mic*_*551 17
如果您仅使用整数值来维护顺序,您需要访问正确的值,那么您不需要任何额外的代码。您可以使用内置值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
}
Run Code Online (Sandbox Code Playgroud)
您只需调用以下方法即可访问序数值:
Types.FOO.ordinal
Run Code Online (Sandbox Code Playgroud)
要获得正确的枚举值,您可以简单地调用:
Types.values()[0] //Returns FOO
Types.values()[1] //Returns BAR
Types.values()[2] //Returns FOO_BAR
Run Code Online (Sandbox Code Playgroud)
Types.values() 按照声明的顺序返回枚举值。
概括:
Types.values(Types.FOO.ordinal) == Types.FOO //This is true
Run Code Online (Sandbox Code Playgroud)
如果整数值不匹配顺序 (int_value != enum.ordinal) 或者您使用不同的类型(字符串、浮点数...),那么您需要迭代和比较您的自定义值,因为它已经在本线程中提到过。
Enum#valueOf基于名称。这意味着要使用它,您需要使用valueof("FOO")。该valueof方法还使用一个String,该字符串说明了错误。字符串不是整数。类型很重要。我之所以也提到它的原因是,所以您知道这不是您要寻找的方法。
如果要基于int值获取一个值,则需要定义自己的函数。您可以使用来获取枚举中的值,在这种情况下values(),它会返回Array<Types>。您可以将其firstOrNull用作一种安全的方法,或者first如果您希望使用例外而不是null。
因此,添加一个伴随对象(相对于枚举是静态的,因此您可以通过调用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 }
}
Run Code Online (Sandbox Code Playgroud)
values()每次调用时都会返回一个新的Array,这意味着您应该在本地缓存该数组,以避免每次调用时都重新创建一个数组getByValue。如果在调用values()该方法时调用它,则可能会反复创建它(取决于您实际调用了多少次),这很浪费内存。
如果您要这样做,也可以扩展该功能并根据多个参数进行检查。这些类型的函数不仅限于一个参数。
不过,功能的命名完全取决于您。不一定是getByValue。
一个天真的方法可以是:
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 }
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用
var bar = Types.valueOf(2)
Run Code Online (Sandbox Code Playgroud)
这真的取决于你真正想要做什么。
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]
}
}
Run Code Online (Sandbox Code Playgroud)
Kotlin 中的伴随对象旨在包含属于类但不绑定到任何实例的static成员(如 Java 的成员)。在那里实现该方法允许您通过调用来访问您的值:
var bar = Types.findByValue(2)
Run Code Online (Sandbox Code Playgroud)
如果您讨厌为每种enum类型声明 acompanion object{ ... }要实现EMotorcycleType.fromInt(...). 这是为您提供的解决方案。
EnumCaster 对象:
object EnumCaster {
inline fun <reified E : Enum<E>> fromInt(value: Int): E {
return enumValues<E>().first { it.toString().toInt() == value }
}
}
Run Code Online (Sandbox Code Playgroud)
枚举示例:
enum class EMotorcycleType(val value: Int){
Unknown(0),
Sport(1),
SportTouring(2),
Touring(3),
Naked(4),
Enduro(5),
SuperMoto(6),
Chopper(7),
CafeRacer(8),
.....
Count(9999);
override fun toString(): String = value.toString()
}
Run Code Online (Sandbox Code Playgroud)
用法示例 1:Kotlin 枚举到 jni 并返回
fun getType(): EMotorcycleType = EnumCaster.fromInt(nGetType())
private external fun nGetType(): Int
fun setType(type: EMotorcycleType) = nSetType(type.value)
private external fun nSetType(value: Int)
---- or ----
var type : EMotorcycleType
get() = EnumCaster.fromInt(nGetType())
set(value) = nSetType(value.value)
private external fun nGetType(): Int
private external fun nSetType(value: Int)
Run Code Online (Sandbox Code Playgroud)
用法示例2:分配给val
val type = EnumCaster.fromInt<EMotorcycleType>(aValidTypeIntValue)
val typeTwo : EMotorcycleType = EnumCaster.fromInt(anotherValidTypeIntValue)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3656 次 |
| 最近记录: |