NOTE: This question is not about generic classes, it's about generic functions. (I don't believe it to be a duplicate of this one: it is more specific than that.)
In our project, we have a handful of utility functions to extend Double
and Float
, such as toFixed
(inspired by Javascript's Number.toFixed
)
fun Double.toFixed(digits: Int):String = java.lang.String.format("%.${digits}f", this)
fun Float.toFixed(digits: Int):String = java.lang.String.format("%.${digits}f", this)
As you can see, Double.toFixed
and Float.toFixed
have an identical implementation.
Because there are several other, more complicated extension functions like this, improvements and bug fixes in one version (say, Double.toPrecision
) have to be manually kept in sync (with Float.toPrecision
), which is boring and error prone.
I experimented with moving the duplicated implementations into a shared <templated>
function, but (rightly) it can't access this
in the context of an unbound function.
To illustrate, I was hoping for something like this:
private fun <T>toFixed(digits: Int):String = java.lang.String.format("%.${digits}f", this)
fun Double.toFixed = ::toFixed<Double>
fun Float.toFixed = ::toFixed<Float>
If any language can rock this, surely Kotlin can! Thoughts?
An extension on a generic type can be achieved by using fun <T> T.toFixed(...)
. Doing that, this
is accessible.
The Problem then is, that the extenstion can be used on any type! You can use upper bounds on your T
to restrict it:
fun <T: Number> T.toFixed(...)
If you really have to restrict the extension to only Float
and Double it's necessary to extend the concrete types only. Have a look at the Koltin math
library in addition, might be helpful :) (Available with 1.2-Beta):
https://github.com/JetBrains/kotlin/blob/1.2-Beta/js/js.libraries/src/core/math.kt