gpt4 book ai didi

scala - 自动为案例类生成案例对象

转载 作者:行者123 更新时间:2023-12-04 02:58:56 25 4
gpt4 key购买 nike

如何让 Scala 编译器自动生成 case 对象?

// Pizza class
class Pizza (val crust_type: String)

// companion object
object Pizza {
val crustType = "crust_type"
}

案例对象的所需属性
  • 对于 case class 中的每个属性在 case object 中生成一个属性
  • 将每个对应 case 对象的值设置为属性名称的字符串表示并更改 camelCasesnake_case对于对象属性名称,保留 snake_case对于对象属性值
  • 最佳答案

    您可以创建宏注释

    import scala.annotation.{StaticAnnotation, compileTimeOnly}
    import scala.language.experimental.macros
    import scala.reflect.macros.blackbox

    @compileTimeOnly("enable macro paradise to expand macro annotations")
    class GenerateCompanion extends StaticAnnotation {
    def macroTransform(annottees: Any*): Any = macro GenerateCompanion.impl
    }

    object GenerateCompanion {
    def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = {
    import c.universe._

    annottees match {
    case (c@q"$_ class $tpname[..$_] $_(...$paramss) extends { ..$_ } with ..$_ { $_ => ..$_ }") :: Nil =>

    val vals = paramss.flatten.map(p => {
    val name = p.name.toString
    q"val ${TermName(underscoreToCamel(name))}: String = $name"
    })

    q"""
    $c
    object ${tpname.toTermName} {..$vals}
    """
    }
    }

    def underscoreToCamel(name: String): String = "_([a-z\\d])".r.replaceAllIn(name, _.group(1).toUpperCase)
    }

    并使用它
    @GenerateCompanion
    class Pizza(val crust_type: String)

    Pizza.crustType //crust_type

    新宏:
    import scala.annotation.{StaticAnnotation, compileTimeOnly}
    import scala.language.experimental.macros
    import scala.reflect.macros.blackbox

    @compileTimeOnly("enable macro paradise to expand macro annotations")
    class GenerateCompanion extends StaticAnnotation {
    def macroTransform(annottees: Any*): Any = macro GenerateCompanion.impl
    }

    object GenerateCompanion {
    def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = {
    import c.universe._

    def vals(paramss: Seq[Seq[ValDef]]): Seq[ValDef] =
    paramss.flatten.map(p => {
    val name = p.name.toString
    q"val ${TermName(underscoreToCamel(name))}: String = $name"
    })

    annottees match {
    case (c@q"$_ class $tpname[..$_] $_(...$paramss) extends { ..$_ } with ..$_ { $_ => ..$_ }") :: Nil =>
    q"""
    $c
    object ${tpname.toTermName} {
    ..${vals(paramss)}
    }
    """

    case (c@q"$_ class $tpname[..$_] $_(...$paramss) extends { ..$_ } with ..$_ { $_ => ..$_ }") ::
    q"$mods object $tname extends { ..$earlydefns } with ..$parents { $self => ..$body }" :: Nil =>
    q"""
    $c
    $mods object $tname extends { ..$earlydefns } with ..$parents { $self =>
    ..$body
    ..${vals(paramss)}
    }
    """
    }
    }

    def underscoreToCamel(name: String): String = "_([a-z\\d])".r.replaceAllIn(name, _.group(1).toUpperCase)
    }

    用法:
    @GenerateCompanion
    class Pizza(val crust_type: String, val foo_foo: Int)

    object Pizza {
    def bar: String = "bar"
    }

    Pizza.crustType //crust_type
    Pizza.fooFoo //foo_foo
    Pizza.bar //bar

    关于scala - 自动为案例类生成案例对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51048310/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com