gpt4 book ai didi

scala - 如何在 Scala 宏中创建类或对象?

转载 作者:行者123 更新时间:2023-12-05 00:21:34 24 4
gpt4 key购买 nike

我正在尝试使用宏从案例类生成一个伴随对象,但我很难找到如何实现这一点的任何示例。

例如:

case class Person(name: String, age: Int, id: Option[Int] = None)

如果我做:
object PersonTable extends TypedTable[Person]

我希望它生成:
object PersonTable extends Table("PERSON") {
val name = column[String]("NAME")
val age = column[Int]("AGE")
val id = column[Option[Int]]("ID")
}

此外,我希望能够扩展它并添加其他字段:
object PersonTable extends TypedTable[Person] {
val created = column[Timestamp]("TIMESTAMP")
}

它会产生:
object PersonTable extends Table("PERSON") {
val name = column[String]("NAME")
val age = column[Int]("AGE")
val id = column[Option[Int]]("ID")
val created = column[Timestamp]("TIMESTAMP")
}

编辑

在阅读了宏注释(感谢 Eugene 和 Mario)之后,我创建了以下代码:
class table[T] extends StaticAnnotation {
def macroTransform(annottees: Any*) = macro TableGenerator.impl
}

object TableGenerator {
def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._

def modifiedObject(objectDef: ModuleDef): c.Expr[Any] = {
val ModuleDef(_, objectName, template) = objectDef
val ret = q"""
object $objectName {
def test() = println("Wahoo!")
}
"""
c.Expr[Any](ret)
}

annottees.map(_.tree) match {
case (objectDecl: ModuleDef) :: _ => modifiedObject(objectDecl)
case x => c.abort(c.enclosingPosition, s"@table can only be applied to an object, not to $x")
}
}
}

然后尝试像这样使用它:
@table[String] object MyCoolObject
MyCoolObject.test()

第一行工作正常,但第二行说它找不到测试方法。如何使测试方法可见?

最佳答案

不幸的是,很难在网上找到好的宏示例——尤其是 2.11。我终于能够让一切正常工作,所以我想为以后遇到相同问题的任何人提供代码链接。

https://github.com/outr/scalarelational/blob/master/mapper/src/main/scala/org/scalarelational/mapper/typedTable.scala

再次感谢 Eugene 和 Mario 的精彩回答,让我找到了答案。

关于scala - 如何在 Scala 宏中创建类或对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31420237/

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