Mastering Kotlin Scope Functions
Welcome back to Aria's Corner. I'm Aria ๐ท and today I'm talking about...
Oh boy. Kotlin scope functions... Buckle up. Or don't. I mean, who really reads blog posts about scope functions for fun these days... ๐ except maybe me, in my pajamas. Anyways, let's do this! ๐ช
Kotlin Scope Functions: Tiny Tools, Big Headaches (or Not)โ
If you've ever stared at Kotlin code and thought, "Why are there five ways to do basically the same thing"โyou're not alone. I've been there, holding my coffee too tight, muttering at the screen, "Do I really need another one?"
Kotlin gives us five main scope functions: let, run, with, apply, and also. Each one is like a tiny little... okay, like a tiny magical creature that does something slightly different, and you have to guess which one fits where. Some people swear by them, some people treat them like cursed objects.
Let's (pun intended ๐) Break It Downโ
1. let
Use this little guy when you're dealing with something that might not be there.
Like, you open a box. If a cat's in it, you pet it then it follows you around ๐บ. If not, then you don't get to pet the cat ๐. Its kinda like Schrodinger's cat... except with less grim consequences.
Check this:
val name: String? = "Mooncake"
name?.let { println(it.uppercase()) }
So basically, if name isn't there, it prints MOONCAKE. Otherwise... nothing happens. It's that simple, yet still... silent but deadly. Like a cat on your keyboard.
2. run
So run is pretty much let but there's no it.
name?.run { println(this) } // Prints "mooncake".
It's the one I reach for when I don't feel like typing it over and over.
3. with
So what's the deal with with? (sorry, I had too ๐).
This one is basically run except you pass it the box like with(name) { ... } rather than the usual name.run { ... }.
So with would turn our run example into something like:
with (name) { println(this) } // Prints "mooncake".
Honestly, it might look flashy, like I'm serving tea to the function and it's all "why, thank you waitress." But it's basically still just run all dressed up, smort as can be. Same difference, really.
4. apply
This one's a little different... but good different. Trust me ๐. Its pretty much let, but where that returned whatever was in the box, apply just returns the box itself.
Like this:
val uppercase = name.apply { this.uppercase() }
println(uppercase) // Prints "MOONCAKE"
If you're anything like me, you're probably wondering why in the heck fire apply exists. Stumped me too... But basically, it's great for messing with something before saving it to a variable.
Think of it like decorating a cupcake... you add your sprinkles, and then you get to keep the cupcake.
I like it for saving me from having to type out the variable twice, also like run, there's no it's to type either! ๐ช
5. also
At this point, you're probably realizing these scope functions are just twisted versions of each other. And... you'd be right.
also is like a hybrid of let and run. You get to borrow using it from let. AND it returns the box just like run.
You could say its the best (or worst) of both worlds, depending on what you like.
It works like this:
val uppercase = name?.also {
println(it) // Prints "mooncake".
it.uppercase()
}
println(uppercase) // Prints "MOONCAKE".
I use it when I want to do something extra, like logging, without breaking the flow.
So... Which One Should You Use?โ
Ah. The million-dollar question. And the frustrating part: it depends.
- Want to do stuff and get a result? Use
letorrun. - Want to do stuff and keep your thing?
applyoralso. - Wanna be fancy? Use the fancy function
with.
Don't overthink it. Just pick what works for you. If you're not sure why you're using one, you're probably misusing it (been there, done that... way too much).
Oh and of course, I've misused also like three times already... AND that's just this week. You don't judge me, and I won't judge you ๐
My Tiny, Personal Tipโ
Of course, my little blog post here on "Aria's Corner" (yep, that's a self promo ๐) isn't the defacto piece on scope functions.
If you found any of my rambling confusing... join the club ๐ I'm kidding, of course. Anyways, you can always leave me a sweet comment or do a deep dive of the official docs: Scope functions.
Bonus stuff: I also keep a sticky note on my monitor (next to the one reminding me to water my pink tulips) that says:
let: Do stuffrun: Do stuff and more stuffwith: Fancy stuffapply: Do stuffalso: Do stuff and more stuff (with more typing)
Til next time. Your friend, Aria ๐ท
