记录Scala 2.10宏

时间:2012-12-12 13:22:22

标签: scala macros documentation scala-2.10 scala-macros

我将从一个例子开始。这里的元组List.fill相当于Scala 2.10中的一个宏:

import scala.language.experimental.macros
import scala.reflect.macros.Context

object TupleExample {
  def fill[A](arity: Int)(a: A): Product = macro fill_impl[A]

  def fill_impl[A](c: Context)(arity: c.Expr[Int])(a: c.Expr[A]) = {
    import c.universe._

    arity.tree match {
      case Literal(Constant(n: Int)) if n < 23 => c.Expr(
        Apply(
          Select(Ident("Tuple" + n.toString), "apply"),
          List.fill(n)(a.tree)
        )
      )
      case _ => c.abort(
        c.enclosingPosition,
        "Desired arity must be a compile-time constant less than 23!"
      )
    }
  }
}

我们可以使用以下方法:

scala> TupleExample.fill(3)("hello")
res0: (String, String, String) = (hello,hello,hello)

这个家伙在几个方面都是一只奇怪的鸟。首先,arity参数必须是文字整数,因为我们需要在编译时使用它。在Scala的早期版本中,对于一个方法,即使告诉它的一个参数是否是编译时文字,也没办法(据我所知)。

其次,Product返回类型is a lie - 静态返回类型将包括由参数确定的特定arity和元素类型,如上所示。

那么我该如何记录这件事呢?我现在不期待Scaladoc的支持,但是我希望有一种常规或最佳实践的感觉(除了确保编译时错误消息是清楚的),这将使运行到宏方法 - 其中对于Scala 2.10库的用户来说,这可能是一种奇怪的需求 - 不那么令人惊讶。

新宏系统最成熟的演示(例如,ScalaMockSlick,其他列出的here)在方法级别仍然相对无证。任何示例或指针都将受到赞赏,包括来自具有类似宏系统的其他语言的示例或指针。

1 个答案:

答案 0 :(得分:1)

我认为记录这些内容的最佳方式是使用示例代码,因为Miles一直在他的无形实验macro based branch中进行。