Estoy intentando escribir un rasgo (en Scala 2.8) que puede ser mezclado en una clase de caso, que permite a sus campos a ser inspeccionada en tiempo de ejecución, para un propósito particular, la depuración. Quiero recuperarlos en el orden en que fueron declarados en el archivo fuente, y me gustaría omitir cualquier otro campo dentro de la clase de caso. Por ejemplo:Reflexión sobre una clase caso Scala
trait CaseClassReflector extends Product {
def getFields: List[(String, Any)] = {
var fieldValueToName: Map[Any, String] = Map()
for (field <- getClass.getDeclaredFields) {
field.setAccessible(true)
fieldValueToName += (field.get(this) -> field.getName)
}
productIterator.toList map { value => fieldValueToName(value) -> value }
}
}
case class Colour(red: Int, green: Int, blue: Int) extends CaseClassReflector {
val other: Int = 42
}
scala> val c = Colour(234, 123, 23)
c: Colour = Colour(234,123,23)
scala> val fields = c.getFields
fields: List[(String, Any)] = List((red,234), (green,123), (blue,23))
La implementación anterior está claramente viciado porque adivina la relación entre la posición de un campo en el producto y su nombre por la igualdad del valor que en el campo, por lo que el siguiente, por ejemplo, no va a funcionar :
Colour(0, 0, 0).getFields
¿Hay alguna manera de que esto se pueda implementar?
Hay un error en el código. Los valores no son únicos y, por lo tanto, va a sobrescribir los valores con (field.get (this) -> field.getName) cuando se mueva de lo que un campo tiene un nombre de pila. Vea una versión reescrita de su código a continuación. –
@SagieDavidovich De hecho, como se señaló, "la implementación anterior es claramente defectuosa" –