Search code examples
kotlinkotlin-android-extensionskotlin-interopkotlin-null-safety

Kotlin - chaining of safe call operator. unnecessary operator calls


Take the following example which uses safe call operator (?.):

class Sample {
    class A(
            val sampleB: B? = B()
    )

    class B(
            val sampleC: C = C()
    )

    class C(
            val sampleInt: Int = 1
    )

    fun test() {
        val intInC: Int? = A().sampleB?.sampleC?.sampleInt
    }
}

I understand that we need a safe call operator on sampleB. But why do we need the safe call operator on sampleC. If I remove that operator, it does not compile.

Based on my understanding of the operator, if sampleB were null, the line returns null. And if sampleB is not null, we can be sure that sampleC is not null, based on its type. But why does Kotlin force safe call operator on sampleC ?


Solution

  • A().sampleB?.sampleC?.sampleInt
    

    parses as

    ((A().sampleB)?.sampleC)?.sampleInt
    

    The types are

    A(): A
    A().sampleB: B?
    (A().sampleB)?.sampleC: C?
    ((A().sampleB)?.sampleC)?.sampleInt: Int?
    

    Because the type before sampleC is a B?, the ?. is required.