Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

376
Visualizações
How can I generalize functions on an enum class in Kotlin?

How can I create a class which could be more reusable with enum classes, as I might have few more classes later on? My point is to make it more reusable, flexible and global for other usage.

enum class PaymentMethodType(val type: String) {

    PAYPAL("Paypal"),
    VISA("Visa"),
    MASTERCARD("MasterCard"),
    VISA_DEBIT("VISA Debit"),
    LPQ_CREDIT("Lpq Credit");

    companion object {

        private val TAG: String = this::class.java.simpleName

        fun fromString(name: String): PaymentMethodType? {
            return getEnumFromString(PaymentMethodType::class.java, name)
        }

        private inline fun <reified T : Enum<T>> getEnumFromString(c: Class<T>?, string: String?): T? {
            if (c != null && string != null) {
                try {
                    return enumValueOf<T>(
                        string.trim()
                            .toUpperCase(Locale.getDefault()).replace(" ", "_")
                    )
                } catch (e: IllegalArgumentException) {
                    Log.e(TAG, e.message)
                }
            }
            return null
        }
    }
}
over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

You can generalize your getEnumFromString function by creating an interface and having your companion object implementing it. An extension on this interface will let you call the function directly on the companion of your enum class.

This will do the trick:

interface EnumWithKey<T : Enum<T>, K> {
    val T.key: K
}

/* The reified type parameter lets you call the function without explicitly 
 * passing the Class-object.
 */
inline fun <reified T : Enum<T>, K> EnumWithKey<T, K>.getByKey(key: K): T? {
    return enumValues<T>().find { it.key == key }
}

Now you can create your PaymentMethodType like this:

enum class PaymentMethodType(val type: String) {
    PAYPAL("Paypal"),
    VISA("Visa"),
    MASTERCARD("MasterCard"),
    VISA_DEBIT("VISA Debit"),
    LPQ_CREDIT("Lpq Credit");

    companion object : EnumWithKey<PaymentMethodType, String> {
        // Just define what the key is
        override val PaymentMethodType.key
            get() = type
    }
}

And voila, now you can do this:

println(PaymentMethodType.getByKey("Paypal")) // Prints PAYPAL

The EnumWithKey interface can now be reused by just having the companion object of an enum implementing it.

over 4 years ago · Santiago Trujillo Relatório

0

Well? How about this code?

enum class PaymentMethodType(val type: String) {
    PAYPAL("Paypal"),
    VISA("Visa"),
    MASTERCARD("MasterCard"),
    VISA_DEBIT("VISA Debit"),
    LPQ_CREDIT("Lpq Credit");

    companion object {
        private val TAG: String = PaymentMethodType::class.simpleName

        fun fromString(name: String?): PaymentMethodType? {
            val maybeType = PaymentMethodType.values().firstOrNull { it.type == name }
            if (maybeType == null) {
                Log.e(TAG, "No corresponding PaymentMethodType for $name")
            }
            return maybeType
        }
    }
}

Just made getEnumFromString method simpler like this way.

Moreover, if you want to make your PaymentMethodType more "reusable, flexible and global", add some abstract method onto your PaymentMethodType or consider using Sealed class in this case. We can guess that many payment methods require their own protocols, and implementing it by enum requires an externalised when or if-else branch to do so. For example, the code should be looks like this:

fun paymentProcessor(payment: PaymentMethodType): Boolean {
    return when (payment) {
        PAYPAL -> { processPaypalPayment() }
        VISA   -> { processVisaPayment() }
        // ...
    }
}

which is not bad unless numbers of payment methods are limited but not quite desirable. We can remove this insidious if or when keyword like this way(retaining enum class approach):

enum class PaymentMethodType(val type: String) {
    PAYPAL("Paypal") {
        override fun processPayment(): Boolean {
            TODO("Not implemented.")
        }
    },
    VISA("Visa") {
        override fun processPayment(): Boolean {
            TODO("Not implemented.")
        }
    },
    // ... more types ...
    ;

    abstract fun processPayment(): Boolean

    // ...
}

With either approach, we can eliminate when keyword in paymentProcessor method I demonstrated like this:

fun paymentProcessor(payment: PaymentMethodType): Boolean {
    return payment.processPayment()
}

I don't explain sealed class approach since the code is not much different compare to enum class approach in this case. The official document may help.

Hope this helps.

over 4 years ago · Santiago Trujillo Relatório

0

Get all enum values with PaymentMethodType.values(), then use find() to get the one you need:

fun fromString(type: String): PaymentMethodType? = PaymentMethodType.values().find { it.type.toLowerCase() == type.toLowerCase() }
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda