Kotlin data classes and nullable types

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.

Upvotes: 11

Views: 5982

Answers (2)

hotkey
hotkey

Reputation: 147901

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.

Upvotes: 11

Ilya
Ilya

Reputation: 23105

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.

Upvotes: 3

Related Questions