Playing with `values classes` right now. We’re usi...
# getting-started
j
Playing with
values classes
right now. We’re using Location objects a lot in our app and I thought they would be a very good fit to replace
longitude: Double
et
latitude: Double
. After a couple hours trying to slowly replace them in our codebase, looks like they are a lot less convenient than I expected... In particular, is there no simple way to do some basic math operations on them out of the box? For exemple, doing some area bounds computation like:
Copy code
val averageLatitude =
    (area.bottomLeft.latitude + area.topLeft.latitude + area.bottomRight.latitude) / 3
Looks like I have 2 options right now: • call
.value
on all latitude objects • follow the suggestion and create a
Latitude.plus
member function Am I missing anything?
k
Maybe something like
Copy code
interface Coord<T> {
    val value: T
}

operator fun Coord<Double>.plus(other: Coord<Double>) = this.value + other.value

@JvmInline
value class Lat(override val value: Double) : Coord<Double>

@JvmInline
value class Long(override val value: Double) : Coord<Double>

fun main() {
    val lat = Lat(10.0)
    val long = Long(10.0)

    val sum = lat + long
}
Would be ok?
j
hmmm, slightly better than my second option since then, I don’t have to define
plus
for both latitude and longitude, thanks for the suggestion 🙂 thinking on giving up on it anyway 😕 the feature looked promising but it’s not quite there yet, just learned that it doesn’t work with room for example 😞
k
This doesn't look right to me. Having Long and Lat share the same interface means you can add a longitude to a latitude, which would be meaningless. You wouldn't want to do that.
You can probably fix that using
value class Lat(override val value: Double) : Coord<Lat>
or similar
🙌 1
j
I see your point, thank for the suggestion 🙂 🙏
p
The downside is you lose your type safety as
Lat.plus(Lat) -> Double
. That may or may not be desired. By defining twice (should only really need to be written once… and copy/paste/search/replace should get you there quickly) you gain
Lat.plus(Lat) -> Lat
- you can also still have
Lat.div(Int) -> Double
etc as required. One option to avoid the pain of writing this might be to look into KSP to generate some math operations automagically.
K 1