jcminarro
03/04/2018, 9:18 PMwhen
expresion and I would like to share with you and see what you think about it.
I have created a repo that reproduces the problem that I had, you can check here: https://github.com/JcMinarro/SealedClass
The problem was with some Sealed Class that has some object class
. The IDE, when autocomplete the remaining branches, if some of the cases is an object class
doesn't add the is
operator at the beginning. I though that the operator is
was redundant when it was used inside of when
with an object class
but It is not the same. I had the problem when I serialized/deserialized that object class
and I could see that I got a kotlin.NoWhenBranchMatchedException
Andreas Sinz
03/04/2018, 9:35 PMis
compares the types, without is
it checks whether its the same runtime-instance. if you serialize/deserialize an object
, it is a new runtime instanceAndreas Sinz
03/04/2018, 9:36 PMAndreas Sinz
03/04/2018, 9:36 PMis
when working with a sealed class
jcminarro
03/04/2018, 9:37 PMis
it compare the value. I would like that IDE suggest you to use always is
when you work with a sealed class
jcminarro
03/04/2018, 9:38 PMAndreas Sinz
03/04/2018, 9:39 PMraulraja
03/04/2018, 10:03 PMMySingleton.type
explicit synthetic type to be able to refer to the types of singleton objects but in Kotlin we have ambiguity:
when (a) {
is B -> // type comparison works for class an object
}
when (a) {
B -> //ambiguos comparison equals based comparison takes precedence
}
Both case would compile fine but in the second one the semantics of the program change since when defaults matches to equals comparison.raulraja
03/04/2018, 10:04 PMB
is a class it would be compared by type but if it's an object it would be compared against the object value and not the object type.Andreas Sinz
03/05/2018, 8:40 AMa.equals(B)
where B
is the "only" instance of object B
Andreas Sinz
03/05/2018, 8:54 AMB
is a class. You either need to use is B ->
to compare the types or B() ->
to compare with equals
raulraja
03/05/2018, 10:36 AMB ->
is valid for classes. If B
was a class it would do a type comparison but if it's an object uses equals based comparison. You can see in @jcminarro repo how the test fails even compiling fine. If you add is B ->
then it performs the right comparison. This is going to be confusing as it stands in Kotlin to many users and has the potnetial to introduce runtime woas and bugs because of ambiguity. Refactoring the class to an object is common and when
cases left behind will still compile but yield a different behavior at runtime.Andreas Sinz
03/05/2018, 11:07 AMclass B
, B ->
does not compile here with the message: Classifier 'B' does not have a companion object, and thus must be initialized here
. In his repo he has SomeSealedClass.SomeObjectClass -> false
which is an object and is SomeSealedClass.SomeDataClass -> true
which is a data class. I can't find any occurence of SomeDataClass ->
without is
in his testsraulraja
03/05/2018, 11:40 AM