La mejor forma de manejar instancias de objects múltiples

Debido en parte al hecho de que no puedo crear classs de datos sin parameters en Kotlin, uso object s para esos casos, por ejemplo

 sealed class Node { object Leaf : Node() data class Branch(val left:Node, val right:Node) : Node() } 

El problema es que a veces, termino con varias instancias de la class Leaf . Obviamente, esto no debería ocurrir en general, pero ocurre al serializar y deserializar con algunos frameworks y con algunos casos de testing.

Ahora, podría argumentar que debería arreglar esos casos, pero es difícil saber dónde podrían estar, y no siempre es posible o deseable modificar la semántica de deserialization de los frameworks.

Como tal, quiero que todas las instancias de mis object actúen como el mismo valor, al igual que una data class sin parameters (o una case class parameters en Scala).

Mi mejor solución hasta el momento es la siguiente, incluida en cada object que creo que podría enfrentar este problema:

 object SaneLeaf { override fun hashCode() = javaClass.hashCode() override fun equals(other: Any?) = other?.javaClass == javaClass } 

Obviamente, esto es prolijo y propenso a errores, ya que no parece posible abstraer esas implementaciones a una interfaz. Una superclass funcionaría en casos donde el object no necesita extender otra class, pero a menudo no es el caso.

Alternativamente, puedo crear una class de datos con un parámetro Nothing . Pero eso parece aún más de un truco.

¿Cómo han lidiado los demás con este problema? ¿Hay planes para agregar hashCode y equals implementaciones a objects que siguen la semántica presunta de esas classs (todas las instancias deben ser iguales / mismas hashCode)?

Creo que tener instancias múltiples de la class subyacente de un object es realmente un problema que debe solucionar, pero hay una solución más simple que le permite tener la semántica de igualdad que describió.

Puede definir una class abstracta que realice la lógica de igualdad y hacer que la class sealed henetworkinge de ella, así:

 abstract class SingletonEquality { override fun equals(other: Any?): Boolean = this::class.objectInstance != null && other?.javaClass == this.javaClass || super.equals(other) override fun hashCode(): Int = if (this::class.objectInstance != null) javaClass.hashCode() else super.hashCode() } 

Y el uso:

 sealed class Node : SingletonEquality() { object Leaf : Node() data class Branch(val left:Node, val right:Node) : Node() } 

Aquí, Leaf henetworkingará la implementación equals de SingletonEquality y se comparará de la manera que desee.

  • Usando kotlin con el framework Mvvmfx
  • Kotlin: ¿Cómo puedo invocar un campo lambda que tiene un tipo genérico de su class?
  • Android Keystore? .getKey devuelve null en algunos dispositivos
  • Configurando "build.gradle" para el module Kotlin en Android Studio
  • constructor de escenas independiente para get el proyecto intellij
  • Android - IllegalStateException: cursor.getString (idx) no debe ser nulo
  • Observable.fromCallable () implementación con exception
  • ¿Por qué Kotlin Array <T> no implementa Iterable <T>
  • Interoperabilidad de Kotlin JS y GWT
  • ¿Hay alguna forma de iterar todos los campos de una class de datos sin usar la reflexión?
  • Kotlin inesperado 'reference no resuelta'