Table of Contents
Motivation
In general a code is written by one person. Later the same code is maintained by another person. Since we all grew up in different places, we have different views of what the standard unit is. As shown below, the lack of dimensions makes maintaining a code base harder:
// is that in meters?
// or in miles?
// or even in royal cubit?
val distance = 42
// in km/h ?
// in mph ?
val speed = 88
With user defined literal, it is clear and there is no need for a comment anymore.
val distance = 42.km
val speed = 88.mph
How it works
I learned about user-defined literals for the first time in the language C++. Thanks to the Extension Property
in Kotlin, we can also create custom literals.
data class Distance(val distanceInKm: Double){
companion object {
const val MI_TO_KM = 1.609344
fun createFromMiles(distance: Double): Distance {
return Distance(MI_TO_KM * distance)
}
}
}
// our extensions properties
val Int.km: Distance
get() = Distance(this.toDouble())
val Int.mi: Distance
get() = Distance.createFromMiles(this.toDouble())
// et voilà
val foo: Distance = 42.km
val bar: Distance = 26.mi
By the way, I recommend to have also a look at inline classes even if it is in alpha state. It is very similar to Scala's value classes.
Android Use Case
I recently wanted to change padding in button view. There I was inspired how Jetpack Compose has solved it.
interface ViewHelper {
val ctx: Context
val Int.dp: Int
get() =
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
this.toFloat(),
ctx.resources.displayMetrics
).toInt()
val Int.sp: Float
get() =
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP,
this.toFloat(),
ctx.resources.displayMetrics
)
}
class MainActivity : AppCompatActivity(), ViewHelper {
override val ctx = this
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// ...
button.setPadding(8.dp, 8.dp, 8.dp, 8.dp)
}
}
References
- C++ User-Defined Literals
- Jetpack Compose
- Extension Properties
- Inline Classes
- Cover Image by arielrobin from Pixabay
Top comments (0)