斯卡拉扁平化课程

时间:2015-11-10 08:53:35

标签: scala

我在Scala中定义了以下类:

case class Info {
    name: String,
    age: Int,
    dept: String
}


case class Foo {
    id: String,
    info: Info    
}

有没有办法从Foo和Info中自动获取以下类:

case class FlatFoo {
    id: Option[String],
    name: Option[String],
    age: Option[Int].
    dept: Option[String]
}

1 个答案:

答案 0 :(得分:5)

这看起来像是一个非常核心宏的任务 但我想知道你是否只想缩短像你这样的现场存取器 obj.fieldX.fieldY.fieldZ....
在这种情况下,您可能会对名为Lens的概念感兴趣。这在monocle library

中得到了很好的实施

考虑你的案例类的这种定义:

import monocle.macros.Lenses

@Lenses
case class Info(name: String,
                age: Int,
                depts: List[String]
               )
@Lenses
case class User(id: String,
               info: Info
              )

@Lenses属性为每个字段生成特殊的函数getter& setter。这些镜头隐含地位于伴侣物体中。但你可以添加自己的,组成存在。

import monocle.function.Index._
import monocle.std.list._
object User {
  val name = info ^|-> Info.name
  val age = info ^|-> Info.age
  val mainDept = info ^|-> Info.depts ^|-? index(0)
}

现在有了

val oleg = User("odomontois", Info("Oleg", 23, List("python", "ABAP")))

你可以看到

User.mainDept.getOption(oleg) == Some("python")

(User.age.set(28) andThen User.mainDept.set("scala")) (oleg) ==
  User("odomontois",Info("Oleg",28,List("scala", "ABAP")))