What is the idiomatic way to add a function to a class based on type. The following example uses List as the class, and the Type Parameter <T>
is the class of objects inside of the list. Lets say you want to sort each of these lists with a different comparator based on their type.
data class A(val foo: String)
data class B(val bar: Int)
private val aComparator: Comparator<A> = Comparator { lhs, rhs -> rhs.foo.compareTo(lhs.foo) }
private val bComparator: Comparator<B> = Comparator { lhs, rhs -> rhs.bar.compareTo(lhs.bar) }
fun <T: A> List<T>.sort(): List<T> {
return this.sortedWith<T>(aComparator)
}
fun <T: B> List<T>.sort(): List<T> {
return this.sortedWith<T>(bComparator)
}
This gives an error saying that both sort functions have the same signatures due to Java's overloading rules. In Java I might give them both different identifiable names but it is fairly ugly as Kotlin extensions (e.g. a.sortA() b.sortB()). Kotlin doesn't show sortA to a List< B > so there seems like there would be a better way of writing sort() to handle different comparators on different objects.
The example is pretty simple but imagine if I don't have access to modify class A and B so I could not use inheritance or implement an interface on them. I also thought about adding a comparator to every class and use Any? But that seems cumbersome as well.
One answer seems to be :
@JvmName("sortA")
fun <T: A> List<T>.sort(): List<T> {
return this.sortedWith<T>(aComparator)
}
@JvmName("sortB")
fun <T: B> List<T>.sort(): List<T> {
return this.sortedWith<T>(bComparator)
}
This seems to fix Java's issue with generic type erasure.
Found here : https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With