Я пытаюсь написать черту (в Scala 2.8), которая может быть смешана с классом case, позволяя проверять его поля во время выполнения, для определенной цели отладки. Я хочу вернуть их в том порядке, в котором они были объявлены в исходном файле, и я хотел бы опустить любые другие поля внутри класса case. Например:Отражение класса класса 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))
выше реализация явно испорчена, поскольку она предполагает взаимосвязь между положением полем в Продукту и его именем равенства значения на тех полях, так что следующий, скажем, не будет работать :
Colour(0, 0, 0).getFields
Есть ли способ, которым это может быть реализовано?
Там ошибка в коде. Значения не уникальны, поэтому вы переписываете значения с помощью (field.get (this) -> field.getName) при перемещении, чем одно поле имеет указанное имя. См. Переписанную версию вашего кода ниже. –
@SagieDavidovich Действительно, как уже отмечалось, «вышеупомянутая реализация явно ошибочна» –