Hi. What will be the proper way to create an exten...
# announcements
v
Hi. What will be the proper way to create an extension function for an Enum? I saw this question, but I’m not sure if it’s a correct approach to define a extension for an Enum. https://stackoverflow.com/q/35966447
My use case is to extract this function I have in one Enum class into an extension function:
Copy code
companion object {
   fun methodByValue(value: String) = values().first { it.value == methodValue }
}
m
You could do something like this. It requires that the enum has a companion object that implements the
EnumCompanion
interface though.
Copy code
interface EnumCompanion<T : Enum<T>>

enum class Test {
    A, B, C;
    
    companion object : EnumCompanion<Test>
}

fun EnumCompanion<Test>.print() = print(this)

fun main() {
   Test.print()
}
I actually wrote this answer on SO some time ago that kind of answers your question: https://stackoverflow.com/a/55019478/4137489
v
Not sure I understand this approach either 😀
m
The problem is, you cannot create a function directly on the enum like that without it having a companion object.
And to be able to create a generic extension function on enum companion objects, you have to make the companion objects implement an interface.
v
I don’t understand this function -
fun EnumCompanion<Test>.print() = print(this)
. Where is it located?
m
Just on the top level. It just prints the companion object. In your case, you could implement this function:
Copy code
fun <T> EnumCompanion<T>.methodByValue(value: String) = TODO()
v
Is it a correct way to define an extension function?
Copy code
fun <T> EnumCompanion<T>.methodByValue(value: String) = this.values().first { it.value == methodValue }
It doesn’t compile
m
Right. You need to use
enumValues<T>()
, and that requires
T
to be reified. Look that the definition of
getByKey
in my Stack Overflow answer.
Also,
it.value
will not compile, because the generic
T
doesn't have
value
defined.
v
No other ways to check it’s
value
?
m
Look at my Stack Overflow answer.. That's why I define
val T.key: K
inside the
EnumWithKey
interface.
v
Ok, thanks. I think I will postpone defining the extension fun for an Enum. It’s too complicated for me now 🙂
d
@marstran out of curiosity (not at the right computer to try it myself now) would it be possible make an extension function
fun KClass<MyEnum>.MyExtensionFunction()
so that it could be called as
MyEnum::class.MyExtensionFunction()
?
m
@David Eriksson Tested it. That works too 🙂 The drawback is using reflections for it though.
😁 1
d
::class still counts as reflection, right 😞
I'm no stranger to reflection on the JVM though :)
m
Yes. You also have to do an
import kotlin.reflect.KClass
😉
d
Yeah the EnumCompanion<> way seem superior