在scala中读取异构集合的所有成员的相同属性?

时间:2015-01-20 19:52:52

标签: scala slick

考虑到我们有一个对象集合,它们都是case类,并且它们都有一个字段,比如一个uuid,我们想要收集它们以供进一步使用。在我的特定情况下,对象来自四个不同数据库表的行。在其他情况下,它们可能来自某个异构容器,或者来自管道或其他任何东西。

使用java的内省混合我可以在一个笔划中读取所有uuids,如

val LocalTables=Seq(t1,t2,t3,t4)
for (t <- LocalTables) {
 t foreach ( v => {
  val metodo=v.getClass.getDeclaredMethod("id")
  println(metodo.invoke(v))
  }
}

但我觉得很脏。有没有办法告诉scala去直接访问v.id?

这个具体的用例是用于数据库访问,因此可以通过特定查询轻松解决。但问题更为笼统,我想了解可以使用哪些工具在某些异构值集合上运行 foreach

1 个答案:

答案 0 :(得分:3)

在精确/安全和简单/灵活性之间存在各种选择。很多logic for Haskell适用。想到的选项是:

结构类型

非常容易使用,或多或少安全,即使它们最终编译为反射:

val localTables = Seq[{def id: UUID}](t1, t2, t3, t4)
localTables foreach {t => println(t.id)}

特质

非常安全,但要求您修改类型:

trait HasId { def id: UUID }
case class Something(id: UUID, ...) extends HasId
val localTables = Seq[HasId](...)
...

无形HListpoly

安全灵活,但有点吓人

import shapeless._, hlist._, poly._
object extractId extends Poly1 {
  implicit val caseFoo = at[Foo](_.id)
  implicit val caseBar = at[Bar](_.id)
  ...
}
val localTables = t1 :: t2 :: ... :: HNil // of type Foo :: Bar :: ... :: HNil
val ids: List[UUID] = localTables map extractId toList
ids foreach println