11

I'm new to Kotlin and I don't know why compiler complains about this code:

data class Test(var data : String = "data")

fun test(){
  var test: Test? = Test("")
  var size = test?.data.length
}

Compiler complains with test?.data.length, it says that I should do: test?.data?.length. But data variable is String, not String?, so I don't understand why I have to put the ? when I want to check the length.

2 Answers 2

11

The expression test?.data.length is equivalent to (test?.data).length, and the test?.data part is nullable: it is either test.data or null. Therefore it is not null-safe to get its length, but instead you should use the safe call operator again: test?.data?.length.

The nullability is propagated through the whole calls chain: you have to write these chains as a?.b?.c?.d?.e (which is, again, equivalent to (((a?.b)?.c)?.d)?.e), because, if one of the left parts is null, the rest of the calls cannot be performed as if the value is not-null.

Sign up to request clarification or add additional context in comments.

1 Comment

Ok, I understand now. Thanks you very much!
3

If you don't want to use safe call before each non-nullable component of the call chain, you can get the result of the first safe call into a new variable with the standard extension functions run or let:

// `this` is non-nullable `Test` inside lambda 
val size = test?.run { data.length }   

// or: `it` is non-nullable `Test` inside lambda
val size = test?.let { it.data.length }

Note that size is still nullable Int? here.

1 Comment

Thanks you very much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.