AndroidPub
Published in

AndroidPub

Photo by Dan Dimmock on Unsplash

Let’s talk about Kotlin’s let extension function

Dealing with optionals

var property: Int? = 42fun someMethod() {
if (property != null) {
print(property) // Error
}
}
Smart cast to ‘Int’ is impossible, because ‘property’ is a mutable property that could have been changed by this time
var property: Int? = 42fun someMethod() {
val copy = property
if (copy != null) {
print(copy)
}
}
var property: Int? = 42fun someMethod() {
property.let {
fancyPrint(it) // error
}
}
fun fancyPrint(int: Int) {
print(int)
}
var property: Int? = 42fun someMethod() {
property?.let {
fancyPrint(it)
}
}
fun fancyPrint(int: Int) {
print(int)
}

Understanding the Let function

inline fun <T, R> T.let(block: (T) -> R): R
class MyClass {
var property: Int? = 42

fun someMethod() {
val value = property?.let {
fancyPrint(it)
"success"
}
}

fun fancyPrint(int: Int) {
print(int)
}
fun fancyPrint(string: String) {
print(string)
}
}
property?.let { someValue ->
fancyPrint(someValue)
}
class MyClass {
var property: Int? = 42

fun someMethod() {
val value = property?.let {
fancyPrint(it)
"success"
}
fancyPrint(value) // error
}

fun fancyPrint(int: Int) {
print(int)
}
fun fancyPrint(string: String) {
print(string)
}
}
  • let captures the value T for thread-safe reading
  • If the value is an optional, you probably want to unwrap it first with ?. so that your T is not an optional
  • The scope of let is of the enclosing class, allowing you to access class methods and properties
  • You can return a value that’s of a different type R which will be optional.

What about the failure case?

fun someMethod() {
property?.let {
fancyPrint(it)
} ?: run {
showError()
}
}
class MyClass {
var property: Int? = 42

fun someMethod() {
val value = property?.let {
fancyPrint(it)
"success"
} ?: "No Value"
fancyPrint(value)
}

fun fancyPrint(int: Int) {
print(int)
}
fun fancyPrint(string: String) {
print(string)
}
}

Let’s get Swifty

func someMethod() {
guard let value = property else { return }
fancyPrint(value)
}
fun someMethod() {
val value = property?.let { it } ?: return
// can be simplified to just `property ?: return` too which is
// much simpler, but if you want to log anything additional the
// let syntax is super flexible.
fancyPrint(value)
}

Where to go from here

  • apply
  • run
  • with
  • also

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Codie Westphall

Hey! I'm Codie. I photograph, film, design, program, all the fun things in life really. Currently work as an iOS and Android developer for PocketSmith