https://kotlinlang.org logo
Title
y

Yan Pujante

03/29/2021, 4:54 PM
I have the following piece of logic:
@Composable
fun EditPartUI(part: Part, onDismiss: () -> Unit) { /* */ }

@Composable
fun PartXX() { 
    var pendingPartCreate by remember { mutableStateOf<Part?>(null) }
    
    if(pendingPartCreate == null) {
        ScrollableTab(
            onFabAction = { pendingPartCreate = Part() }) {
            // ....
        }
    } else {
        EditPartUI(pendingPartCreate!!, onDismiss = { pendingPartCreate = null} )
    }
}
The
else
branch does not compile unless I use
pendingPartCreate!!
(smart cast does not work). So is the compiler not smart enough to detect the fact that it cannot change? Or is the compiler rightfully wants to prevent me from shooting myself in the foot?
t

TheMrCodes

03/29/2021, 4:56 PM
The second case your variable is of type var and could be change in the meanwhile from another thread / coroutine
y

Yan Pujante

03/29/2021, 4:57 PM
but how exactly can another thread change it? It is defined inside the composable function, no other code has access to it
t

TheMrCodes

03/29/2021, 4:59 PM
Maybe someone can explain it in more detail but one requirement for smart cast is that the variable is immutable (for example a val or a parameter) So if you would use an extra variable as 'snapshot' of the value of pendingPartCreate it would work. something like this
[...] 
val currentPendingPart = pendingPartCreate
if (currentPendingPart == null) {
    // casted to null
} else {
    // casted to notnullable Part
} 
[...]
j

jim

03/29/2021, 5:10 PM
There is no way of knowing when
EditPartUI
might invoke the
onDismiss
lambda. By convention, Compose widgets typically only invoke such callbacks on the main thread in response to a UI event, but this is not guaranteed by any system that the compiler can depend upon. In particular, the
EditPartUI
widget might launch a thread and invoke that lambda between the null check and the usage.
y

Yan Pujante

03/29/2021, 5:12 PM
I am not launching any thread but I guess I get the point, I need to copy the variable to be certain
a

albertosh

03/30/2021, 7:00 AM
I am not launching any thread
You know it. The compiler doesn’t. So it goes for a conservative approach. In the end,
!!
operator is just that, you telling the compiler that it’s OK to use a nullable var without any check because you know that it won’t be null
👍 1