斯卡拉扁平化课程

Mat*_*aco 0 scala

我在Scala中定义了以下类:

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


case class Foo {
    id: String,
    info: Info    
}
Run Code Online (Sandbox Code Playgroud)

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

case class FlatFoo {
    id: Option[String],
    name: Option[String],
    age: Option[Int].
    dept: Option[String]
}
Run Code Online (Sandbox Code Playgroud)

Odo*_*ois 5

这看起来像一个非常核心宏的任务.
但是我想知道你是否只想缩短你的字段访问者. obj.fieldX.fieldY.fieldZ....
在这种情况下你可能会对名为Lens的概念感兴趣.这在单片机库中实现得很好

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

import monocle.macros.Lenses

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

@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)
}
Run Code Online (Sandbox Code Playgroud)

现在有了

val oleg = User("odomontois", Info("Oleg", 23, List("python", "ABAP")))
Run Code Online (Sandbox Code Playgroud)

你可以看到

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

(User.age.set(28) andThen User.mainDept.set("scala")) (oleg) ==
  User("odomontois",Info("Oleg",28,List("scala", "ABAP")))
Run Code Online (Sandbox Code Playgroud)