Overview
The let()
function is one of a handful of scope functions defined in the Kotlin standard library.
Example
val size = "Hello".let {
println(it)
it.length
}
In this example, the string “Hello” is printed, and then its length is assigned to the size
variable.
Characteristics
When the let()
extension function executes:
- the receiver object that
.let()
is called upon is available as the lambda argument - by default, namedit
- the result of
let()
will be the result of the code block passed to it
Transformation
The let()
method is frequently used to transform an object.
fun rotateLeft(it: String) = "${it.subSequence(1, it.length)}${it.first()}"
"greetings".let { rotateLeft(it) }
Of course, you can also use a function reference, which would make more sense in this example.
"greetings".let(::rotateLeft)
Alternatives
Transformation to members
If you’re transforming an object into one of its properties or the result of one of its functions, there’s no need for let()
- just access the properties or functions directly.
// Unnecessary
"greetings".let { it.length }
"greetings".let { it.toUpperCase() }
// Preferred
"greetings".length
"greetings".toUpperCase()
Using extension methods
In cases where you’ve got a transformative function (such as rotateLeft()
above), you might prefer to craft it as an extension function:
fun String.rotateLeft() = "${this.subSequence(1, this.length)}${this.first()}"
"greetings".rotateLeft()
This gives us the same characteristics as the direct property/function access discussed above (in the Transformation to members section) – meaning there’d be no need for the let()
call – and it handles nulls more elegantly by allowing you to use a safe-call operator, like this:
var maybeGreetings: String? = null
maybeGreetings?.rotateLeft()
Comparison with map()
If you come from a Java 8 background, you might be familiar with the .map()
function on Stream
and Optional
. Be careful not to confuse Kotlin’s let()
with Kotlin’s map()
.
map()
- similar toStream.map()
. It operates on the items in a collection.let()
- similar toOptional.map()
. It operates on the object itself. If the object is a collection, thenlet()
affects the collection as a whole, not the individual items in the collection.
More Alternatives
Choosing from among the different scope functions can be confusing. Check out the guide, Understanding Kotlin’s let(), also(), run(), and apply() for information on which function to pick.