https://kotlinlang.org logo
Title
r

Rachel Carandang

06/26/2022, 3:19 PM
Question about use of lateinit var: I’ve only seen it used in class variables, but I recently came across it in a PR from someone new to Kotlin that used it inside a method call. What are the patterns and advice for using lateinit var inside methods? Or should it be avoided? Is the below use of lateinit valid?
fun degreesToDirection(degrees: Float?): Direction {
            var smallestDistance: Float = Float.POSITIVE_INFINITY
            lateinit var direction: Direction

            degreesMapping.entries.forEach {
                if (abs(it.value - (degrees ?: 0f)) < smallestDistance) {
                    direction = it.key
                    smallestDistance = (degrees ?: 0f) -  it.value

                }
            }

            return direction
        }
j

Joffrey

06/26/2022, 3:30 PM
There is nothing really wrong about this
lateinit var
per se. But doing this sort of loop to initialize a variable in Kotlin is usually a smell. For instance, is it expected to iterate over all the mappings here? Usually the first match should stop the loop
j

Javier

06/26/2022, 3:39 PM
I can't think a lot about it now, but you probably can change that to reduce + first (or fold + first and so on), so you can avoid mutability. But not sure if the alternative is so readable compared to the current one
v

Vampire

06/26/2022, 3:40 PM
fun degreesToDirection(degrees: Float?) =
    degreesMapping.minByOrNull { (_, mappedDegrees) ->
        abs(mappedDegrees - (degrees ?: 0f))
    }!!.key
For instance, is it expected to iterate over all the mappings here? Usually the first match should stop the loop
First match, when searching for a minimum? 😉
😄 2
As far as I understood, lateinit is practially always a smell, be it as property or not and is mainly for integrate into existing frameworks like Spring that sets the value after creating the object and similar.
j

Joffrey

06/26/2022, 3:48 PM
Lol indeed for a minimum you have to, I actually didn't really read the code in details (I'm on mobile) but the general pattern of declaring a var and init via a loop seemed wrong
s

Starr

06/26/2022, 3:49 PM
isn't there `minBy`/`maxBy` for this kind of stuff?
v

Vampire

06/26/2022, 3:50 PM
Yes, I just gave the imho proper code, just see my first comment
j

Joffrey

06/26/2022, 3:52 PM
In Kotlin 1.7 you shouldn't need
minByOrNull
+
!!
v

Vampire

06/26/2022, 3:57 PM
Which else would I use? I only found
minBy
which is deprecated and should be replaced by
minByOrNull
.
j

Javier

06/26/2022, 3:59 PM
they removed minBy in 1.6 to bring back it in 1.7
the previous implementation of minBy can be nullable, so to follow the standard naming, they removed for one version so they can have both, minBy and OrNull in 1.7
v

Vampire

06/26/2022, 4:01 PM
I see o_O
Or
fun degreesToDirection(degrees: Float?) =
    degreesMapping.minWith(compareBy { (_, mappedDegrees) ->
        abs(mappedDegrees - (degrees ?: 0f))
    }).key
And https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/min-by.html shows
minBy
only not deprecated for common, js, and native, but deprecated for jvm
🤔 1
v

Vampire

06/26/2022, 8:23 PM
Maybe a documentation problem due to the back and forth with deprecation?
r

Rachel Carandang

06/26/2022, 9:12 PM
Wow thanks for the good discussion! Good to know