2017-08-07 72 views
5

Alanı temsil eden belirli bir String değerinden bir vaka sınıfının alan değerini nasıl çıkarmalıyım? ÖrneğinErişim erişimi nasıl Durum sınıfı alanı Değer Alanın dize adı

:

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

Şimdi burada bir dize name veya age i değişken a değeri ayıklamak istediğiniz verilen. Bunu nasıl yaparım? Bunun yansımayı kullanarak yapılabileceğini biliyorum ama tam olarak nasıl emin değilim?

+0

Ve değeri güvenli bir şekilde ayıklamak istiyorum. Yani, eğer alan yok ise, hiç bir şey almamalıyım. – Sidhant

+0

Hangi kullanım durumunda, bir 'Kişinin' '' '' '' '' '' yaş '' olması beklenemez? –

cevap

0

Aklınızda vardı, ama yapacak bir match açıklamada, bu Person vaka sınıfına saygılarımla değişikliklerle çok genel ya da genişletilebilir değil, ama yansıma kullanmama temel gereklilikleri karşılıyorsa tam olarak ne olduğunu bilmiyorum: Yorumlarınız göre

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 

GÜNCELLEME:

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

Ya sonra bir sarıcı yazmam gerek. Bir sarıcı işlevi el ile yazmadan çalışma zamanında bunu gerçekleştirmek istiyorum. – Sidhant

+1

sonra belki ödeme çıkışsız: [shapeless lenses] (https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-2.0.0#boilerplate-free-lenses-for-arbitrary-case-classes – Yaneeve

3

neler Aradığınızı Shapeless lensler kullanarak elde edebilirsiniz. Size olmayan bir varolan alan ayıklamak çalışırsanız

res0: String = myName 

: Bu aynı zamanda bir saha aslında derleme zamanında bir vaka sınıfında bulunduğunu kısıtlaması koymak yerine zaman geçerli olacaktır:

import shapeless._ 

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

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

nameLens.get(p) 

Verim

import shapeless._ 

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

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

nonExistingLens.get(nonExistingLens) 

Derleyici bağırır:

çok daha güçlü bir garantisidir bir derleme zamanı hatası olsun
Error:(5, 44) could not find implicit value for parameter mkLens: shapeless.MkFieldLens[Person,Symbol with shapeless.tag.Tagged[String("bla")]] 
val nonExistingLens = lens[Person] >> 'bla 
+1

Her zamanki gibi güzel. Bir vardir. – slouc