[英]Writing Macro for Positive Integers
Given the following types: 给出以下类型:
sealed trait PosIntCheckResult
case class LteZero(x: Int) extends PosIntCheckResult
case object NotConstant extends PosIntCheckResult
I'm trying to write a macro that checks whether the given Int
is greater than 0. 我正在尝试编写一个宏来检查给定的Int
是否大于0。
import reflect.macros.Context
def getInt(c: Context)(value: c.Expr[Int]): Either[PosIntCheckResult, Int] = {
import c.universe._
value.tree match {
case Literal(Constant(x)) => if (x > 0) Right(x) else Left(LteZero(x))
case _ => Left(NotConstant)
}
}
But Any
shows up for the x
value: 但是Any
显示x
值:
Test.scala:29: type mismatch;
found : Any
required: Int
case Literal(Constant(x)) =>
if (x > 0) Right(x) else Left(LteZero(x))
How can I get the compiler to expect an Int
rather than Any
? 如何使编译器期望Int
而不是Any
?
You just have to match on patterns where x
is an Int
: 您只需要匹配x
为Int
:
case Literal(Constant(x: Int)) => //When using x here, it is an Int
Read about pattern matching on type and the other types of pattern matching in the docs . 在文档中阅读有关类型的模式匹配和其他类型的模式匹配。
You should also note that your macro will need to return an Expr
in order to work. 您还应该注意,宏必须返回Expr
才能起作用。 You can use reify
to construct the desired Exprs
at each case
. 您可以使用reify
建设所需的Exprs
在每个case
。 Read about reify
and def macros
here . 在此处阅读有关reify
和def macros
信息 。 I'm not sure why this needs to be a macro, but if you're just learning the techniques, something like this might work: 我不确定为什么这需要是一个宏,但是如果您只是在学习技术,则可能会执行以下操作:
object Macros {
def getInt(value: Int): Either[PosIntCheckResult, Int] = macro getIntImpl
def getIntImpl(c: Context)(value: c.Expr[Int]): c.Expr[Either[PosIntCheckResult,Int]] = {
import c.universe._
value.tree match {
case x@Literal(Constant(const: Int)) if const > 0 => reify(Right(c.Expr[Int](x).splice))
case x@Literal(Constant(_: Int)) => reify(Left(LteZero(c.Expr[Int](x).splice)))
case _ => reify(Left(NotConstant))
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.