What is the difference between two line of codes:
1.
viewHolderRef?.get()?.adapterPosition.let {
viewHolderRef?.get()?.adapterPosition?.let
I know that it can affect on the type of the argument that the lambda expression gets but in difference i mean, is there a situation when in one of the expression the let will run and in the second know (with refer to null issue)
v?.let
means: if v
is null
, then just make the entire expression null
(the let
method won't even be called because it'll be terminated early), and if it's not null
, then change the type of the expression to be non-nullable then keep going with the property chain. So, v?.let
will only call the function if v
is non-null.
On the contrary, v.let
will always call let
, regardless if v
is null or not, so the parameter is nullable (since there's no guarantee it isn't null like with v?.let
. The difference is best demonstrated with this code:
fun test(v: String?) {
v.let { it: String? -> println("v.let: $it") }
v?.let { it: String -> println("v?.let: $it") }
}
fun main () {
test(null)
println("----------")
test("foo")
}
This outputs:
v.let: null
----------
v.let: foo
v?.let: foo
As you can see, when calling it on a null
output, only v.let
runs and prints null
, whereas on a non-null output, both let
statements run. You can also see a difference in the types of the parameters: v.let
takes in a String?
, whereas v?.let
takes in a String
.