简体   繁体   English

为正整数编写宏

[英]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 : 您只需要匹配xInt

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 . 在此处阅读有关reifydef 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM