Why doesn't Kotlin have data objects?


#1

Scala has not only cases classes (the counterpart to data classes) but also case objects.

trait Status {
  val code: Int
}

case object NotFound extends Status {
  val code = 404
}

I’d find that useful in Kotlin, too. Is there a reason why Kotlin doesn’t have data objects?


#2

You can use an object as a descendant of a sealed class. Data objects don’t exist because the methods that the compiler generates for a data class don’t make sense for an object.


#3

Why wouldn’t that make sense? Say for example I had a HashSet, which would contain instances of a sealed class:

val status = setOf(NotFound, Ok("abc"))

Then I could check with contains whether the value is in my set or not, what in turn would use hashCode behind the scenes.


#4

Yes, you can do that. The default implementation of java.lang.Object.hashCode() used by all classes that don’t override it works perfectly fine in this scenario.


#5

However the default implementation of toString makes an object implementing sealed class differ from the data class, see this issue for details: https://youtrack.jetbrains.com/issue/KT-4107


#6

Ok, you’re right in this case. But except from the already mentioned toString implementation, the usual object doesn’t have component1..n methods. I’m just wondering why Scala does have case objects and Kotlin does not. Most things in Scala have a proper reason.


#7

The componentN methods are not an implementation of any interface, so you can’t really use a destructuring declaration with an instance of a sealed class without knowing the specific implementation (unless you explicitly declare all componentN methods as abstract methods in the sealed class definition). And using a destructuring declaration on an object knowing that it is an object doesn’t seem to be particularly useful, because objects rarely contain mutable data.