2017-08-07 75 views
5

如何從表示字段的給定字符串值中提取案例類字段的值。如何訪問訪問權限案例類字段值字段的字符串名稱

例如:

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

現在,這裏給出一個字符串nameage我想提取變量a值。我該怎麼做呢?我知道這可以用反射來完成,但我不確定如何?

+0

我想能夠安全地提取值。這意味着如果該領域不在那裏,我應該得到無或什麼。 – Sidhant

+0

在什麼樣的情況下,'Person'不會被指定爲'name'或'age'? –

回答

0

不知道你想到的是什麼,但match聲明可以做,它不是非常通用的,或者對於Person case類的更改不是可擴展的,但它確實符合不使用反射的基本要求:

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

然後也許結帳shapeless: [無形鏡片](https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-2.0.0#boilerplate-free-lenses-for-arbitrary-case-classes ) – Yaneeve

3

什麼你正在尋找可以實現使用無形鏡片。這也把那場在編譯時的情形類實際存在的約束,而不是運行時間:

import shapeless._ 

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

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

nameLens.get(p) 

產量:

res0: String = myName 

如果您嘗試提取一個不存在的領域,你獲得編譯時錯誤,這是一個更強大的保證:

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