I know people have stylistic opinions about this, ...
# compose
s
I know people have stylistic opinions about this, (Extract function, use ?.let{} and so on) but how about correctness, is there any possible issue I could face by adding
!!
to pass a non-null version of a nullable local mutable state like this:
Copy code
@Composable fun foo() {
  var x : Int? by remember { mutableStateOf(0) }
  if (x != null) {
    Bar(x!!)
  } else {
    ...
  }
}
Or is there a chance that my
!!
there will be problematic and actually crash?
h
Yeah, this behavior is annoying. There is an issue to allow some kind of
stable
delegates to allow smartcasts: https://youtrack.jetbrains.com/issue/KT-27325/Allow-smartcasts-for-well-behaved-delegates
e
the proposed
@MonotonicNonNull
doesn't work for this since
x = null
is allowed
s
Thanks for the youtrack links! Would be good to see some improvements on this in general. However ephemient, I am sorry but I don’t quite understand what you mean by that?
e
and I don't think doing this based on the delegate type will help;
Copy code
var x : Int? by remember {
    mutableStateOf(0).apply {
        thread {
            while (true) {
                Thread.sleep(100)
                setValue(null)
                Thread.sleep(100)
                setValue(1)
            }
        }
    }
}
has the all the same types
h
Yeah, that's theoretically true, but updating the value causes a recomposition, the function will be executed again with the new value that is stable during one execution. And you should not set a mutableState inside a recomposition.
e
it's unquestionably bad code, but I don't think it's anything like the
lazy
case (which is truly well-behaved)
s
Right, so as long as I am not doing something obviously wrong or stupid, and I am properly using it as it’s intended to (never change the value top-level in composition) then I should really feel safe doing
!!
in such places.
e
you could do the React-like thing as well
Copy code
val (x, setX) = remember { mutableStateOf<Int?>(0) }
if (x != null) { ... }
setX(...)
s
I would like to avoid that tbh, as it forces a state read at the level which this is defined, instead of deferring it to whenever it is actually read which is often within a smaller recomposition scope, therefore potentially avoiding unnecessary recompositions.