【问题标题】:Scala Macros: How to create setter function for case classesScala 宏:如何为案例类创建 setter 函数
【发布时间】:2014-01-20 22:23:49
【问题描述】:

我想使用宏来生成案例类的设置器。例如:

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

Macro.mkSetter[Person, String]("name") : Person => String => Person

我尝试了以下实现,但我不断得到以下结果

error: scala: Error: Unknown source file: embeddedFile--QuasiquoteCompat.scala@6....

(我正在使用带有宏天堂 2.0.0-SNAPSHOT 的 scala 2.10.3)

object Macro {

  def mkSetter[A, B](fieldName: String): (A,B) => A = macro mkSetter_impl[A,B]

  def mkSetter_impl[A: c.WeakTypeTag, B: c.WeakTypeTag](c : Context)(fieldName: c.Expr[String]): c.Expr[(A,B) => A] = {
    import c.universe._
    val (aTpe, bTpe) =  (weakTypeOf[A], weakTypeOf[B])

    val constructor = aTpe.declarations.collectFirst {
      case m: MethodSymbol if m.isPrimaryConstructor => m
    }.getOrElse(c.abort(c.enclosingPosition, s"Cannot find constructor in ${weakTypeOf[A]}"))

    val field = constructor.paramss.head.find(
      _.name.decoded == fieldName.toString()
    ).getOrElse(c.abort(c.enclosingPosition, s"Cannot find constructor field named in $fieldName"))

    c.Expr[(A,B) => A](q"{(a: $aTpe, b: $bTpe) => a.copy(${field.name} = b)}")
  }
} 

我确实意识到_.name.decoded == fieldName.toString() 不是检查方法名称的正确方法(即使_.name.decoded == "name" 似乎没问题)

加分项: 使用可变参数对具有相同类型的参数进行泛化宏,例如

 def mkSetter[A, B](fieldNames: String*): A => B => B ... => A = macro mkSetter_impl[A,B]

谢谢!

【问题讨论】:

  • 您能否提供有关您的环境的更多详细信息,例如在 github 上发布一个项目?您面临的问题似乎与您尝试编写的宏无关。只需进行几个小改动,我就能够成功运行它。
  • 谢谢@EugeneBurmako。这是我正在处理的project
  • sbt compilesbt test 都可以。我需要做一些特别的事情来重现这个问题吗?
  • 我添加了一些 macro tests 与 sbt 一起传递。但是,当我尝试运行相同的测试时,我遇到了与以前使用 intellij(社区版 v 13.0.1)相同的错误。

标签: scala scala-macros


【解决方案1】:

似乎是由https://github.com/scalamacros/paradise/issues/11 引起的。本周我计划解决这个问题,所以应该很快就好了。您可以在 scalamacros.org (http://scalamacros.org/news/rss.xml) 上订阅更新或在 Twitter 上关注我,以便在部署修复程序时收到通知。

【讨论】:

    猜你喜欢
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    • 2022-11-29
    相关资源
    最近更新 更多