Hey, I want to precise my `Double` usage in my pro...
# announcements
h
Hey, I want to precise my
Double
usage in my project with physical classes, like kiloWatt per Hour. before:
Copy code
data class Holder(val output: Double)
now:
Copy code
data class Holder(val output: Kwh)

value class Kwh(val value: Double)
Now I want to use the default math operators, plus, minus unaryPlus, unaryMinus. Is there any possibility to create default operator functions without copy paste?
b
Hmm, interface with default operator fun implementations?
s
typealias instead of holder class can be used. Otherwise you have to add those functions yourself and delegate it to the Double object
h
@Sourabh Rawat I don't want to use type aliases, otherwise you could assign a kiloWatt per Hour to a variable of type Voltage. Unfortunately
Copy code
value class Kwh(val double: Double): Number by double
does not work for value classes. @Big Chungus Yeah, I use this workaround currently too, but I hoped, there would be a better way
b
You could do extension functions on marker interface as well
h
@Big Chungus But extension functions only move the copy paste methods, and don't reduce them at all 😄 But I think, my experiment is obsolete, as @JsExport is not supported on
value class
, see also https://youtrack.jetbrains.com/issue/KT-46202 FYI:
Copy code
@JvmInline
@JsExport
@Serializable
public value class Kwh(public override val value: Int) : Unit<Int, Kwh> {
    public override fun from(value: Int): Kwh = value.kwh
}

public val Int.kwh: Kwh get() = Kwh(this)

public interface Unit<MathT, T> {
    public val value: MathT
    public fun from(value: MathT): T
}

@JvmName("plusInt")
public operator fun<T: Unit<Int, T>> Unit<Int, T>.plus(other: T): T = from(value + other.value)
@JvmName("minusInt")
public operator fun<T: Unit<Int, T>> Unit<Int, T>.minus(other: T): T = from(value - other.value)
@JvmName("unaryMinusInt")
public operator fun<T: Unit<Int, T>> Unit<Int, T>.unaryMinus(): T = from(-value)

public operator fun<T: Unit<Double, T>> Unit<Double, T>.plus(other: T): T = from(value + other.value)
public operator fun<T: Unit<Double, T>> Unit<Double, T>.minus(other: T): T = from(value - other.value)
public operator fun<T: Unit<Double, T>> Unit<Double, T>.unaryMinus(): T = from(-value)