2017-08-07 5 views
5

フィールドを表す指定された文字列値からケースクラスのフィールドの値を抽出する方法を教えてください。例えばアクセス方法ケースクラスフィールド値フィールドからの文字列の名前

case class Person(name: String, age: Int) 
val a = Person("test",10) 

が今ここで私は、変数aから値を抽出したい文字列nameまたはageを与えられました。私はこれをどのようにして行うのですか?私はこれが反射を使って行うことができることを知っていますが、私はどのように正確ではないのですか?

+0

私は値を安全に抽出したいと考えています。フィールドがない場合は、Noneまたは何かを取得する必要があることを意味します。 – Sidhant

+0

どのようなユースケースでは、 'Person'は' name'や 'age'を持つことが期待できませんか? –

答えて

0

matchステートメントは、Personケースクラスの変更に関してはあまり一般的でも拡張性もありませんが、リフレクションを使用しないという基本的な要件を満たしています。

scala> val a = Person("test",10) 
a: Person = Person(test,10) 

scala> def extract(p: Person, fieldName: String) = { 
    | fieldName match { 
    |  case "name" => p.name 
    |  case "age" => p.age 
    | } 
    | } 
extract: (p: Person, fieldName: String)Any 

scala> extract(a, "name") 
res1: Any = test 

scala> extract(a, "age") 
res2: Any = 10 

scala> extract(a, "name####") 
scala.MatchError: name#### (of class java.lang.String) 
    at .extract(<console>:14) 
    ... 32 elided 

コメントどおりUPDATE:

scala> case class Person(name: String, age: Int) 
defined class Person 

scala> val a = Person("test",10) 
a: Person = Person(test,10) 


scala> def extract(p: Person, fieldName: String) = { 
    | fieldName match { 
    |  case "name" => Some(p.name) 
    |  case "age" => Some(p.age) 
    |  case _ => None 
    | } 
    | } 
extract: (p: Person, fieldName: String)Option[Any] 

scala> extract(a, "name") 
res4: Option[Any] = Some(test) 

scala> extract(a, "age") 
res5: Option[Any] = Some(10) 

scala> extract(a, "name####") 
res6: Option[Any] = None 

scala> 
+0

しかし、私はラッパーを書く必要があります。私は手動でラッパー関数を書くことなく、実行時にこれを実現したい。 – Sidhant

+1

おそらくチェックアウトシェイプレス: [形のないレンズ](https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-2.0.0#boilerplate-free-lenses-for-arbitrary-case-classes ) – Yaneeve

3

何あなたが探しているのは、シェイプレスレンズを使用して達成することができます。 、あなたをあなたは非既存のフィールドを抽出しようとした場合

res0: String = myName 

:これは、フィールドが実際にコンパイル時にケースクラスに存在する制約を置くのではなく、時間を実行します:

import shapeless._ 

case class Person(name: String, age: Int) 

val nameLens = lens[Person] >> 'name 
val p = Person("myName", 25) 

nameLens.get(p) 

利回りを

import shapeless._ 

case class Person(name: String, age: Int) 

val nonExistingLens = lens[Person] >> 'bla 
val p = Person("myName", 25) 

nonExistingLens.get(nonExistingLens) 

コンパイラが叫ぶ:

はるかに強い保証で コンパイル時エラーを取得 ​​3210
+1

ニース、いつものように。 upvoteをしてください。 – slouc

関連する問題