Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: enums with associated values; function inside 'enum entry' gets `unresolved reference` error

Tags:

android

kotlin

I need to create a list of events with a string as name and a list of pairs as properties, some events properties are the static value, some need dynamically changed, so I create specific functions inside the enum entry to update it but complied with error unresolved reference:

Actually, what I want to implement is a list of enums with associated values, something like these articles mentioned:

  • KT-4075 Allow setters overloading for properties, or
  • Kotlin: single property with multiple setters of different types, or
  • Using Kotlin’s sealed class to approximate Swift’s enum with associated data

Because I have more than 100 events, 95% of them are static, only several of them need to be updated during runtime, so sealed class might not suit my situation:

    enum class Event(val eventName: String, vararg eventProperties: Pair<String, String?>) {
        LOGIN_CLICKED("Login", ("View" to "button clicked")),

        LOGIN_SUCCEED("Login", ("Type" to "succeed")),

        LOGIN_ERROR("Login") {
            fun errorMessage(errorMessage: String) {
                eventProperties = listOf("ErrorType" to errorMessage)
            }
        },

        // ... some other events

        LIST_ITEM_CLICKED("LIST") {
            fun listItemName(itemName: String) {
                eventProperties = listOf("View" to itemName)
            }
        };

        var eventProperties: List<Pair<String, String?>>? = listOf(*eventProperties)


// Although this approach can fix my problem, but I don't prefer it,
// because these functions are only meaningful to specific enum item,
// I don't want them be opened to all enum items.
//
//        fun errorMessage(errorMessage: String) {
//            eventProperties = listOf("ErrorType" to errorMessage)
//        }

//        fun listItemName(itemName: String) {
//            eventProperties = listOf("View" to itemName)
//        }
    }

    fun main(args: Array<String>) {

        // unresolved reference
        println(Event.LOGIN_ERROR.eventProperties)
        Event.LOGIN_ERROR.errorMessage("error password")
        println(Event.LOGIN_ERROR.eventProperties)
    }
like image 858
li2 Avatar asked Sep 14 '26 14:09

li2


1 Answers

Because I have more than 100 events, 95% of them are static, only several of them need to be updated during runtime, so sealed class might not suit my situation

Why wouldn't it? If you are bothered with slightly longer declarations:

object LoginClicked : Event("Login", mapOf("View" to "button clicked")) 
\\ vs
LOGIN_CLICKED("Login", mapOf("View" to "button clicked"))

you can create a helper enum class for them:

sealed class Event(val eventName: String, val eventProperties: Map<String, String?>) {
   enum class Basic(val eventName: String, val eventProperties: Map<String, String?>) {
        LOGIN_CLICKED("Login", mapOf("View" to "button clicked")),
        LOGIN_SUCCEED("Login", mapOf("Type" to "succeed")),       
        ...
   }

   class BasicEvent(b: Basic) : Event(b.eventName, b.eventProperties)

   class LoginError(errorMessage: String) : Event("Login", mapOf("ErrorType" to errorMessage))
   ...
}
like image 194
Alexey Romanov Avatar answered Sep 17 '26 04:09

Alexey Romanov