ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Follow publication

Don’t abuse Kotlin’s scope functions

Source of image

Scope functions

Kotlin’s standard library contains several functions whose sole purpose is to execute a block of code within the context of an object.

When you call such a function on an object with a lambda expression provided, it forms a temporary scope.

M𝐚𝐤𝐞 𝐬𝐮𝐫𝐞 𝐰𝐡𝐞𝐧 𝐲𝐨𝐮 𝐮𝐬𝐞 𝐊𝐨𝐭𝐥𝐢𝐧’𝐬 𝐬𝐜𝐨𝐩𝐞 𝐟𝐮𝐧𝐜𝐭𝐢𝐨𝐧𝐬 𝐲𝐨𝐮 𝐮𝐧𝐝𝐞𝐫𝐬𝐭𝐚𝐧𝐝

  • What each of those functions does
  • How receiver accessible within the function’s scope [it, this]
  • What they return
https://kotlinlang.org/docs/scope-functions.html

Accessing nullable properties

  • Let say we have a property called binding in our fragment which is nullable
private var binding: FragmentBlankBinding? = null

How we can access this property in our code in a null-safe manner

  • with : If you have a lot of properties you will end up using ? everywhere in with’s block
with(binding) {
this?.root?.isVisible = true
}

How we can improve this :

  1. let : Although now you are null-safe and you don’t need to repeat ? but you need to use it to access any property of the receiver 😬
binding?.let {
it
.root.isVisible = true
}

2. run : I prefer using this over all the other options because it’s null-safe and concise

Here you can access the properties of the receiver without repeating this everywhere

binding?.run {
root.isVisible = true
}

Creating objects

  • Many developers writing code in Kotlin but they follow Java’s coding style
val intent = Intent()
intent.putExtra("Key", "value")
intent.putExtra("Key1", "value")

How we can improve 👆 this code to make sure it’s concise and Kotlin friendly:

  • let : returns the result of thelambda
val intent = Intent().let {
it
.putExtra("Key", "value")
it.putExtra("Key1", "value")
it.action = "CUSTOM_APP_ACTION" // Unit
}
// here intent's type will be Unit 🥵// you can fix this by moving/removing last statementval intent = Intent().let {
it
.putExtra("Key", "value")
it.action = "CUSTOM_APP_ACTION"
it.putExtra("Key1", "value") // Intent ✅
}
  • apply : returns its receiver

val intent = Intent().apply {
putExtra("Key", "value")
putExtra("Key1", "value")
action = "CUSTOM_APP_ACTION"
}
// here intent's type will be Intent ✅

When to use

with, let, apply, also, run

  • If the property is nullable, you can use let or run
val supportedJVM: String? = nullsupportedJVM?.run {receiver is avialble using this keyword   // Lambda result will be the return value
}

supportedJVM?.let { receiver is avialble using it keyword
// Lambda result will be the return value
}
  • If the property is non-nullable, you can use with
with(languageName) { receiver is avialble using this keyword

//
Lambda result will be the return value
}
  • You can use also when you want to do something additional work with an object orresult of some other function or expression e.g.
var formattedPrice = ""val price = 10.plus(5).also { receiver is avialble using it keyword

formattedPrice = "Price is ${it * 2}"

// Context object will be the return value
}

😊😊 👏👏👏👏 HAPPY CODING 👏👏👏👏 😊😊

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Written by Nav Singh

Google Developer Expert for Android | Mobile Software Engineer at Manulife | Organizer at GDG Montreal

Responses (3)