I bet you didn’t know about these features in Kotlin
If you think you know everything about Kotlin, think again; Kotlin never fails to surprise you.
Kotlin’s first stable was released in 2016 and Google shifted to Kotlin as its preferred language on 7th May 2019. My first interaction with Kotlin was on 11th March 2019, and it has been my favourite language ever since. However, recently I came across a blog by Kaushik Gopal that blew my mind. After some playing around with these features, it makes me love Kotlin even more. Here are five features in Kotlin you might not have heard of before.
Feature #0: Functional Interfaces
If you are an Android Developer, you know the setOnClickListener
function available on all View
s. In Java, you would work like this:
public class MainActivity {
private ActivityMainBinding binding = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater);
setContentView(binding.getRoot());
binding.getButton().setOnClickListener(new View.OnClickListener() {
Toast.makeToast(MainActivity.this, "Clicked", Toast.LENGTH_SHORT)
.show();
});
}
}
Disclaimer: My Java is a little weak now, so please ignore any obvious mistakes :)
With this same code, if we wish to convert this to Kotlin, you would probably have something like the following:
class MainActivty {
private val binding by lazy(LazyThreadSafetyMode.NONE) {
ActivityMainBinding.inflate(layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.button.setOnClickListener(object : View.OnClickListener() {
override fun onClick(view: Button) {
Toast.makeText(this@MainActivity, "Clicked", Toast.LENGTH_SHORT)
.show()
}
}
}
}
Normally, there is no other way to do this. However, do you actually write this code? You instead treat the parameter as a regular lambda expression. Can you guess how that happens?
Say hello to functional interfaces
fun interface View.OnClickListener {
fun onClick(view: View)
}
What is happening in the back is that this interface has only one method. Hence, we can describe this as a Single Abstract Method(or SAM). When you create an interface with one method, you can define it as a functional interface. This enables you to write your code as follows:
class MainActivty {
private val binding by lazy(LazyThreadSafetyMode.NONE) {
ActivityMainBinding.inflate(layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.button.setOnClickListener {
Toast.makeText(this@MainActivity, "Clicked", Toast.LENGTH_SHORT)
.show()
}
}
}
Feature #1: Typealias
I believe typealias
is one of the most common features that is used by developers. If you have a very long type, you could reduce that into something short and meaningful that makes your code a lot cleaner.
/********** DON'T **********/
fun getAllNearbyCoordinates(
radius: Float,
point: Pair<LatitudeF, LongitudeF>
): List<Pair<LatitudeF, LongitudeF>> {...}
/************ DO **********/
typealias GeoPoint = Pair<LatitudeF, LongitudeF>
fun getAllNearbyCoordinates(
radius: Float,
point: GeoPoint
): List<GeoPoint> {...}
This article entails many best practices to use in Kotlin to write cleaner code.
Feature #2: Import alias
This is a feature that I recently learnt about in Kotlin. Not only can you rename a big type name, but also a class that you’re importing.
import com.google.firebase.ktx.Firebase as Fb
object Authentication {
private val auth = Fb.auth
var user = auth.currentUser
// ...
}
Feature #3: Value classes
This feature is mindblowing when you think of it. This has been introduced fairly recently with Kotlin 1.7.
The logic comes from a language called Haskell where they use a keyword called newtype
. Essentially, you want to pass in values of the same type, but different names, but at the same time, not get confused between them. Allow me to elaborate…
What you could do is something along the lines of
typealias MyLatitude = Float
typealias MyLongitude = Float
fun getLocation(): Pair<MyLatitude, MyLongitude> {
val lat = 20f
val long = -40f
return lat to long
}
However, you could most easily make the mistake of doing long to lat
instead and your code would compile.
Now, what if you create data class
es for these instead?
data class MyLatitude(val value: Float)
data class MyLongitutde(val value: Float)
fun getLocation(): Pair<MyLatitude, MyLongitude> {
val lat = MyLatitude(20f)
val long = MyLongitude(-40f)
return lat to long
}
Yay, you have solved the problem. You cannot return long to lat
without a compilation error. However, do you think it is the most optimum solution? Imagine the memory space it would take if you had a dozen hundred of these classes. Instead, we can use value classes.
@JvmInline value class MyLatitude(val value: Float)
@JvmInline value class MyLongitude(val value: Float)
fun getLocation(): Pair<MyLatitude, MyLongitude> {
val lat = MyLatitude(20f)
val long = MyLongitude(-40f)
return lat to long
}
value class
es will treat the class name as a type alias but will prevent you from exchanging between the two properties.
Feature #4: Data Objects
This too is a fairly recent update to Kotlin. data object
s are geared towards a developer standpoint. We would normally have data class
es with one line of code and it would generate a pretty toString()
method for us. Ironically, object
s did not have this despite not having much inside of it. Hence, this basic feature has been added to make printing objects neater.
object Power
data object DataPower
fun main() {
println(Power) // prints Power@439f5b3d
println(DataPower) // prints DataPower
}
Kotlin: A modern programming language
that makes developers happier — JetBrains
These new additions to Kotlin make me fall in love with it more as the day passes. Kotlin is constantly growing. If you visit Kotlin’s official page, you will find this quote and I couldn’t agree more.
This story is part of my series where I write articles about advanced programming in Kotlin. Do check it out!
If you wish to read every article from me, consider joining the Medium
program with this referral link.
Want to connect?
My GitHub profile.
My Portfolio website.