46

We can write the code with or without let as follows.

var str = "Hello World"
str.let { println("$it!!") }

OR

var str = "Hello World"
println("$str!!")

What is the Actual use of let?.Is that more memory efficient or more readable?

Jinesh Francis
  • 3,377
  • 3
  • 22
  • 37

3 Answers3

71

let is one of Kotlin's Scope functions which allow you to execute a code block within the context of an object. In this case the context object is str. There are five of them: let, run, with, apply, and also. Their usages range from but are not exclusive to initialization and mapping.

They are all very similar but they differ in terms of how the context object is referenced and the value that is returned. In the case of let the context object is referenced by the it keyword as opposed to the this keyword. The return value is whatever is returned from the lambda code block. Other scope functions like apply will return the context object instead.

Because let returns whatever the lambda block evaluates to, it is most suited to performing a mapping of some kind:

var upperStr = str.let { it.toUpperCase()}

apply is a more suited function for what you are doing.

To answer your question as to which code is more preferable, it really depends on what you are using the scope function for. In the above case there is no reason to use let. If you are using IntelliJ it will give a warning saying the call to let is redundant. Readability here is a matter of preference, and may be preferred.

The let function is useful when you wish to perform a null safe operation on an Object by using the the safe call operator ?. When doing this the let code block will only be executed if the object is not null. Another reason to use let is if you need to introduce new variables for the operation but you want to confine them to the scope of the let block. This is true for all scope functions, so I reiterate that let is best used for a mapping operation.

Edit: The let function should incur no additional cost. Normally we would expect the lambda/Code-block to be compiled to a Function object but this is not the case for an inline function in Kotlin for which the compiler will emit code not dissimilar to the second code example you have given. See the documentation for more information.

Dean
  • 1,833
  • 10
  • 28
47

One of usages you can check nullable types

var str: String? = null
str?.let { println("$it!!") }

it's equal

if (str != null) {
   System.out.println(str);
}

in Java, but shorter and more useful

Artem Botnev
  • 2,267
  • 1
  • 14
  • 19
  • 1
    Shame that `?.let {} ?: ` is not equivalent to `if(!=null) else {}` so you might want to use the `let` only in actual assignments and not all over the code – EpicPandaForce Oct 29 '19 at 11:41
  • 3
    @EpicPandaForce but `if(!=null) else {}` could also be written as something like `?.let { /* if != null content */ } ?: run { /* else content */ }`... or did you mean something else? – Roland Oct 29 '19 at 12:17
  • @Roland Exactly, but the two statements are actually not equivalent. So people should generally not use this `?: run {` stuff at all unless they are 100% sure they know what they are doing. Otherwise, use `if else`. – EpicPandaForce Oct 29 '19 at 13:08
  • 1
    @EpicPandaForce depends on how you use it, right? if we skip "equivalent" for a moment (because under the hood they are really more different) at least we can say that the following will lead to the same result: `val x = if (y != null) y+1 else z` is similar to `val x = y?.let { it + 1 } ?: run { z }` ... with the latter being a bit safer in case that `y` is mutable and altered in another thread... – Roland Oct 29 '19 at 13:29
4

let takes the object it is invoked upon as the parameter and returns the result of the lambda expression. Kotlin let is a scoping function wherein the variables declared inside the expression cannot be used outside.

One of the examples would be here :

fun main(args: Array<String>) {
    var str = "Hello World"
    str.let { println("$it!!") }
    println(str)

}

You can find more information on Kotlin let function here

Omkar C.
  • 755
  • 8
  • 21