如何获得 Scala 命名参数和默认参数以使用宏
How can I get Scala Named and Default arguments to work with macros
给定 scala 版本 2.11.7 和这个宏定义:
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
package object macrotest {
def namedMacro(c: Context)(a: c.Expr[Int]): c.Expr[Int] = {
println("the int expr was " + a)
a
}
def named(a: Int = 1) = macro namedMacro
}
这个调用:
object NamedMacroTest {
def main(args: Array[String]) {
named()
//named(a = 5) // or this
}
}
为什么我会看到这个错误?
Error:(5, 10) macro applications do not support named and/or default
arguments
我该怎么做才能避免出现错误,同时仍然能够使用命名参数和默认参数调用宏?
根据 the 2.11 docs。
本来应该回去的
原始问题已解决 in this PR,其中详细说明了挑战。
最终由于技术原因at this attempt被击落。他们不喜欢进行脱糖然后失去原始应用程序的样子;并且他们不想执行转换然后必须撤消它。
一个想法是在省略 arg 时让自适应接管:
scala> :pa
// Entering paste mode (ctrl-D to finish)
def m[A: c.WeakTypeTag](c: Context)(i: c.Expr[A]): c.Expr[Int] = {
import c.universe._
if (i.tree.tpe <:< typeOf[Int]) i.asInstanceOf[c.Expr[Int]]
else if (i.tree.tpe <:< typeOf[Unit]) c.Expr[Int](q"42")
else c.abort(null, "Nope") }
// Exiting paste mode, now interpreting.
m: [A](c: scala.reflect.macros.whitebox.Context)(i: c.Expr[A])(implicit evidence: c.WeakTypeTag[A])c.Expr[Int]
scala> def f[A](i: A): Int = macro m[A]
defined term macro f: [A](i: A)Int
scala> f(1)
res9: Int = 1
scala> f()
warning: there was one deprecation warning; re-run with -deprecation for details
res10: Int = 42
scala> f("") // I don't remember where they keep NoPosition
java.lang.NullPointerException
只做一些不同的事情会更容易,比如通过采用空参数列表的方法间接进行。比较 和评论。
给定 scala 版本 2.11.7 和这个宏定义:
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
package object macrotest {
def namedMacro(c: Context)(a: c.Expr[Int]): c.Expr[Int] = {
println("the int expr was " + a)
a
}
def named(a: Int = 1) = macro namedMacro
}
这个调用:
object NamedMacroTest {
def main(args: Array[String]) {
named()
//named(a = 5) // or this
}
}
为什么我会看到这个错误?
Error:(5, 10) macro applications do not support named and/or default arguments
我该怎么做才能避免出现错误,同时仍然能够使用命名参数和默认参数调用宏?
根据 the 2.11 docs。
本来应该回去的原始问题已解决 in this PR,其中详细说明了挑战。
最终由于技术原因at this attempt被击落。他们不喜欢进行脱糖然后失去原始应用程序的样子;并且他们不想执行转换然后必须撤消它。
一个想法是在省略 arg 时让自适应接管:
scala> :pa
// Entering paste mode (ctrl-D to finish)
def m[A: c.WeakTypeTag](c: Context)(i: c.Expr[A]): c.Expr[Int] = {
import c.universe._
if (i.tree.tpe <:< typeOf[Int]) i.asInstanceOf[c.Expr[Int]]
else if (i.tree.tpe <:< typeOf[Unit]) c.Expr[Int](q"42")
else c.abort(null, "Nope") }
// Exiting paste mode, now interpreting.
m: [A](c: scala.reflect.macros.whitebox.Context)(i: c.Expr[A])(implicit evidence: c.WeakTypeTag[A])c.Expr[Int]
scala> def f[A](i: A): Int = macro m[A]
defined term macro f: [A](i: A)Int
scala> f(1)
res9: Int = 1
scala> f()
warning: there was one deprecation warning; re-run with -deprecation for details
res10: Int = 42
scala> f("") // I don't remember where they keep NoPosition
java.lang.NullPointerException
只做一些不同的事情会更容易,比如通过采用空参数列表的方法间接进行。比较 和评论。