Kotlin:在when时使用枚举

时间:2019-01-23 21:38:33

标签: kotlin enums

有什么方法可以将枚举的when参数转换为枚举?

 enum class PaymentStatus(val value: Int) {
     PAID(1),
     UNPAID(2) 
 }

fun f(x: Int) {
   val foo = when (x) {
     PaymentStatus.PAID -> "PAID"
     PaymentStatus.UNPAID -> "UNPAID"
   }
}

上面的示例不起作用,因为x是int且提供的值是枚举,如果我按PaymentStatus.PAID.value进行操作,则可以工作,但是当(全面覆盖)when时,我得不到好处,和

when (x as PaymentStatus)

不起作用。

有人有什么想法可以完成这项工作吗?

4 个答案:

答案 0 :(得分:1)

如果需要检查值,可以执行以下操作:

actionContext

或者您可以在枚举类的伴侣对象中创建工厂方法MyFooService myFooService = actionContext.Request.GetDependencyScope().GetService(typeof(MyFooService)) as MyFooService;

fun f(x: Int) {
    val foo = when (x) {
        PaymentStatus.PAID.value -> "PAID"
        PaymentStatus.UNPAID.value -> "UNPAID"

        else -> throw IllegalStateException()
    }
}

答案 1 :(得分:1)

在此特定用例中,您不需要when

由于您的目标是获取具有特定值enum的{​​{1}}元素的名称,因此您可以像这样遍历x的元素,并使用{ {1}}:

PaymentStatus

firstOrNull元素上调用fun getStatusWithValue(x: Int) = PaymentStatus.values().firstOrNull { it.value == x }?.toString() println(getStatusWithValue(2)) // "UNPAID" 将返回其名称。

答案 2 :(得分:1)

以下是将whenenum结合使用的一种可能的解决方法(也许不会完全针对该问题,但我认为在这里作为参考是一个好主意):

package com.company.my_package

import com.company.my_package.MyEnum.*

enum class MyEnum {
    ENUM_ITEM_1,
    ENUM_ITEM_2,
    ENUM_ITEM_3
}

val myCommand1 = { input: Any? -> input.toString() }
val myCommand2 = { input: Any? -> input.toString() }
val myCommand3 = { input: Any? -> input.toString() }
val myElseCommand = { input: Any? -> input.toString() }

fun main() {
    val myValue = null

    when {
        ENUM_ITEM_1 == myValue -> myCommand1(myValue)
        ENUM_ITEM_2 == myValue -> myCommand2(myValue)
        ENUM_ITEM_3 == myValue -> myCommand3(myValue)
        else -> myElseCommand(myValue)
    }
}

答案 3 :(得分:0)

这基本上取决于您要如何解决标识适当的枚举值的问题。其余的可能很容易。

以下是一些解决方案:

  1. 将功能扩展到PaymentStatus.Companion(或将功能集成到PaymentStatus.Companion中):

    fun PaymentStatus.Companion.fromValue(i : Int) = PaymentStatus.values().single { it.value = i } // or if you want another fallback, just use singleOrNull and add ?: with an appropriate default value
    

    when中的用法:

    fun f(x : Int) = when (PaymentStatus.fromValue(x)) {
      PAID -> "PAID" // or PAID.name()
      UNPAID -> "unpaid" //...
    }
    
  2. 对所有枚举使用通用函数

    inline fun <reified T : Enum<T>> identifyFrom(identifier : (T) -> Boolean) = T::class.java.enumConstants.single(identifier) // or again: singleOrNull ?: throw IllegalArgumentException maybe?
    

    具有以下用法:

    fun f(x : Int) = when (identifyFrom<PaymentStatus> { it.value = x }) {
      PAID -> "PAID"
      UNPAID -> "UNPAID"
    }
    

    此变体显然具有以下优点:基本上可以在要基于某个或多个属性获得值的任何enum上重复使用它

  3. 使用when来标识适当的enum

    fun PaymentStatus.Companion.fromValue(i : Int) = when (i) {
      1 -> PAID
      2 -> UNPAID
      else -> IllegalArgumentException("$i is not a valid value for PaymentStatus")
    }
    

    用法与第一个示例相同。但是:除非您有充分的理由,否则我不会使用这种方法。我不使用它的原因:它要求您始终记住要在fromValue函数中同时适应枚举值和其对应的对应项。因此,您总是必须至少两次更新值;-)