2009-10-19 10 views
17

sto imparando Scala e non riesco a trovare il modo di fare questo:Scala: impostare un valore di campo riflessivo dal nome del campo

sto facendo un mapper tra oggetti Scala e google entità AppEngine, quindi se ho avere una classe come questa:

ho bisogno di creare un'istanza di quella classe, in java vorrei ottenere il campo per il suo nome e poi fare field.set(object, value) ma non riesco a trovare il modo di farlo in scala.

Non riesco a utilizzare java reflection poiché i campi di Student sono considerati privati ​​e field.set genera un errore a causa di ciò.

Grazie

risposta

36

Scala si trasforma "var" in un campo privato, un getter e setter uno. Quindi, per ottenere/impostare una var identificandola usando una stringa, è necessario utilizzare la reflection Java per trovare i metodi getter/setter. Di seguito è riportato un frammento di codice che lo fa. Si noti che questo codice viene eseguito in Scala 2.8.0 e che i nomi dei metodi duplicati e gli errori non esistono.

class Student { 
    var id: Long = _ 
    var name: String = _ 
} 

implicit def reflector(ref: AnyRef) = new { 
    def getV(name: String): Any = ref.getClass.getMethods.find(_.getName == name).get.invoke(ref) 
    def setV(name: String, value: Any): Unit = ref.getClass.getMethods.find(_.getName == name + "_$eq").get.invoke(ref, value.asInstanceOf[AnyRef]) 
} 

val s = new Student 
s.setV("name", "Walter") 
println(s.getV("name")) // prints "Walter" 
s.setV("id", 1234) 
println(s.getV("id")) // prints "1234" 
+0

Grazie! è stato davvero utile, ho preso una parte del tuo codice e ho funzionato bene in Scala 2.7.6 – Damian

+0

Puoi anche recuperare il metodo direttamente per nome se usi getClass.getDeclaredMethod se conosci in anticipo i tipi di parametri del metodo! –

+0

Perché è meglio dell'impostazione field.setAccessible (true)? – Yael

Problemi correlati