https://kotlinlang.org logo
#getting-started
Title
# getting-started
a

Alejo

06/02/2022, 10:22 AM
Hi everyone! I want to initialize a
Boolean
variable from another one of type
Boolean?
and if the value is
null
then I will want to check if a value is present in another list and use that value for the initialization. Here is the code:
Copy code
val statuses = listOf("pending", "on-hold", "auto-draft") 
   val status = "pending"
   val isEditable: Boolean? = true
   
   val result = isEditable ?: status in statuses
   print(result)
But this initialization using the Elvis operator always returns
false
, if I move the
status in statuses
to a different variable or I wrap it in a
run {status in statuses}
then the code works as expected. Am I missing something here or this is a bug? You can test the example here: https://pl.kotl.in/4QDgoNvYi
m

max.denissov

06/02/2022, 10:29 AM
Hi! Please, use clarifying parentheses
val result = isEditable ?: (status in statuses)
🙏 1
j

Joffrey

06/02/2022, 10:29 AM
I think the issue is that
isEditable ?: status in statuses
is understood as
(isEditable ?: status) in statuses
, so you need clarifying parentheses around your
in
check:
Copy code
val result = isEditable ?: (status in statuses)
However, I'm surprised this compiles without the parentheses. There might be a bug in how elvis type is considered for contains:
Copy code
statuses.contains(42 ?: "bob") // compiles fine, returns false
statuses.contains(42) // compile error
🙏 1
Mmh actually I believe it has to do with the fact that
List
is covariant in
T
and
contains
can be understood as being applied to a
List<Comparable>
here. The type of
42 ?: "bob"
is likely
Comparable
and thus the
contains
call compiles. The same could be said for
42
alone, but I guess the compiler doesn't go that far. It does work with explicit type argument:
Copy code
statuses.contains<Comparable<*>>(42) // compiles fine
🙏 2
a

Alejo

06/02/2022, 11:52 AM
Great explanation!
Using clarifying parentheses solved the issue. Thanks!
👍 1
4 Views