Tra*_*own 72 documentation macros scala 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!"
)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以使用以下方法:
scala> TupleExample.fill(3)("hello")
res0: (String, String, String) = (hello,hello,hello)
Run Code Online (Sandbox Code Playgroud)
这个家伙在几个方面都是一只奇怪的鸟.首先,arity
参数必须是一个文字整数,因为我们需要在编译时使用它.在Scala的早期版本中,(根据我所知),方法甚至无法判断其中一个参数是否是编译时文字.
其次,Product
返回类型是谎言 - 静态返回类型将包括由参数确定的特定arity和元素类型,如上所示.
那么我该如何记录这件事呢?我不是在这一点期待Scaladoc支持,但我想有约定或最佳实践的意义(不仅仅是确保编译时错误信息是明确的),这将使运行到宏观的方法,其对于Scala 2.10库的用户来说,可能是奇怪的需求 - 不那么令人惊讶.
新宏系统最成熟的演示(例如,ScalaMock,Slick,此处列出的其他系统)在方法级别上仍然相对没有记录.可以理解任何示例或指针,包括来自具有类似宏系统的其他语言的示例或指针.
归档时间: |
|
查看次数: |
2311 次 |
最近记录: |