2011-09-17 17 views
9

PHP introduces a method that allows you to pick out all public values of an instance. Scalaでこれを行う方法はありますか?これは、インスタンス化されたクラス(オブジェクトではない)のすべてのパブリックフィールドのすべての値を取得することです。Scala/Javaでインスタンスのパブリックフィールド(およびそれぞれの値)を取得する

ましょう私たちは、私がこのクラスに

class TestElement(datatype: Datatype, var subject: String, var day: Int, var time: Int) 
    extends DataElement(datatype: Datatype) {  
    def to(group: Group) = group.add(this); 
} 

var element = new TestElement(datatype, "subject", 1, 1); 

を持っていると仮定し、私は問題の方法から必要なもの、地図や値の2つのコレクションを取得することです。

var element.method          // the function I need 
ret: (("subject", "subject"), ("day", 1), ("time", 1)) // its output 

答えて

20

それはベッドのための時間ですので、私は完全な答えのための時間を持っていますが、(プライベートフィールドまたはgetDeclaredFieldselement.getClass.getFieldsの結果を見ていない - あなたはそれらの値を取得するためにFieldオブジェクトにgetValue(element)を呼び出すことができます。そう


今目覚め、そしてまだ良い答え、:

まず、どのようなことがありするプライベートフィールドの件名で、Javaの用語で、あなたのクラスは、公共分野の​​件名を持っていないことに注意してアクセサメソッドsubject()とsubject_ $ eq(String)。

ペアから地図移入、上記のようにあなたがプライベートフィールドオブジェクトを反復処理することができます

:今

def getFields(o: Any): Map[String, Any] = { 
    val fieldsAsPairs = for (field <- o.getClass.getDeclaredFields) yield { 
    field.setAccessible(true) 
    (field.getName, field.get(o)) 
    } 
    Map(fieldsAsPairs :_*) 
} 

あなたはTestElement上でこのメソッドを定義することができますいずれか(thisoを置き換える)、またはより一般的に有効にしますあなたは

implicit def any2FieldValues[A](o: A) = new AnyRef { 
    def fieldValues = getFields(o) 
} 

だから、任意の参照にれるGetFieldsを呼び出すことができるように変換を定義

element.fieldValues 

あなたが望む結果が得られます。

+0

素晴らしいです、ありがとうございます – sdkfasldf

+0

':_ *'構文は何をしますか? –

2

あなたはケースクラスのためにこれに比較的近い何かを行うことができます:あなたはタイプの要素の任意の上、productIteratorの繰り返し処理を期待するとして...

case class SomeEntity(name : String, value : Int, misc : Boolean) 
val s = SomeEntity("Tom", 42, false) 
println(s.productIterator.map(_.toString).mkString(", ")) // "Tom, 42, false" 

。このメソッドは、ケースクラスのみに対して自動的に生成され、フィールドの名前は取得されません。それ以上のものについては、リフレクションを使用する必要があります。そのためには、2.10が出るのを待つことが必要な場合があります。

+0

2.10の変更点 – sdkfasldf

3

フィリップの回答ごとに、ケースクラスに対してこれを行うことができます。

さらに広い意味では、同じ技術がのいずれかサブクラスProductで機能します。ケースクラスだけでなく、タプルも別の明白な例ですが、リストはそれよりはるかに広範です。

ここでは、「既知のサブクラス」を見てみましょう:http://www.scala-lang.org/api/current/scala/Product.html

1

をするだけのノート@duncanのアプローチタイプ-強くすることにより、これを改善しようとする人たちへ:

代わりの戻りを値は任意として型指定されMap[String, Any]は、次の行うことができます:

def propertiesAsPairs() = { 
    val fields = (this.getClass.getDeclaredFields()) 
    for (field <- fields) yield { 
     field.setAccessible(true); 
     (field.getName, field.get(this)); 
    } 
} 
+0

これの戻り値の型は何ですか?それはあなたに何も買っていないArray [Pair [String、Any]]のように私に見えますか? –

0

Scalaは故意valvardef共通のインターフェースになり、そうすることができますREPLコードを壊さずに後者を使って前者の2つをエコーすることができます。

だから、あなたがしたいことをすることは可能ですが、脆いコードになります。それは、すべきではないことです。

+0

私は、このようなデータクラスの場合、ポイントはフィールド内の値を単にシャトルすることだと主張したいと思います。 –

+0

私に質問するように促しましたが、http://stackoverflow.com/q/7477248/97777 –

関連する問題