Klitos Kyriacou
01/15/2025, 6:49 PMwhen
statement require an else
?
data class Person(val name: String, val birthDate: LocalDate)
fun update(person: Person, property: KProperty1<Person, *>, value: Person): Person =
when (property) {
Person::name -> person.copy(name = value.name)
Person::birthDate -> person.copy(birthDate = value.birthDate)
else -> error("Why isn't this exhaustive?")
}
Youssef Shoaib [MOD]
01/15/2025, 6:53 PMArne Jans
01/15/2025, 7:02 PMwhen
is an expression, not a statement (since this update-function is defined by an expression), and for when
-expressions, they always need to be exhaustive, and they always need to have an else
-branch, except for the cases, when the when
-subject (here, the subject is property)
is a Boolean
, enum class, sealed class, or one of their nullable counterparts, but here it is a KProperty1
, which does not meet this requirement. Hence, the else
-Branch is needed.
For details, see the documentation at
https://kotlinlang.org/docs/control-flow.html#when-expressions-and-statements
and
https://kotlinlang.org/docs/data-classes.htmlYoussef Shoaib [MOD]
01/15/2025, 7:06 PMKProperty1
is an interface, as the link shows, and hence one could write a subclass for it.
Also @Klitos Kyriacou, I think extension properties might count too, so exhaustiveness is definitely not a given.Arne Jans
01/15/2025, 7:06 PMYoussef Shoaib [MOD]
01/15/2025, 7:13 PMimport kotlin.reflect.*
data class Person(val name: String, val birthDate: String)
val Person.fullname: String get() = name
fun update(person: Person, property: KProperty1<Person, *>, value: Person): Person =
when (property) {
Person::name -> person.copy(name = value.name)
Person::birthDate -> person.copy(birthDate = value.birthDate)
else -> error("Why isn't this exhaustive?")
}
fun main() {
val person = Person("foo", "bar")
update(person, Person::fullname, person)
}
Also, I think you're looking for Optics for your use caseKlitos Kyriacou
01/16/2025, 9:25 AMproperty.name
). But since this can be sabotaged by a user inheriting from KProperty1
or by using an extension property, I can't have compile-time safety.