scala - 记录 Scala 2.10 宏

标签 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 —静态返回类型将包括由参数确定的具体数量和元素类型,如上所示。

那么我该如何记录这件事呢?我并不期望 Scaladoc 支持在这一点上,但我希望了解约定或最佳实践(不仅仅是确保编译时错误消息清晰),这将使运行宏方法 - 及其潜在的奇怪需求——对于 Scala 2.10 库的用户来说并不奇怪。

新宏系统最成熟的演示(例如 ScalaMockSlick 、其他列出的 here )在方法级别仍然相对没有记录。任何示例或指针将不胜感激,包括来自具有类似宏系统的其他语言的示例或指针。

最佳答案

我认为记录这些内容的最佳方法是使用示例代码,正如迈尔斯在他的实验 macro based branch 中所做的那样。无形的。

关于scala - 记录 Scala 2.10 宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13840784/

相关文章:

c - 向前兼容接口(interface)的函数签名更改

c++ - 我想使用宏多参数始终为空来跟踪日志。 c++ windows 问题

documentation - 如何在不更改默认安装文件的情况下修改 SandcaSTLe 演示样式

documentation - 如何在 doxygen 输出中生成导航树?

scala - 我们如何在 Lift 片段中获取当前页面的 URL?

Scala - 为什么无法覆盖父类(super class)的方法

scala - 如何使用junit的EqualsWithDelta

casting - 将保留关联映射顺序的 Clojure 宏

PHP: The Reflection API - 对 PHP 的很好的补充,但很少使用

scala - 以 DRY 方式扩展 SLICK 表