【问题标题】:Implicit macro. Default implicit value. How?隐式宏。默认隐式值。如何?
【发布时间】:2021-01-15 05:23:09
【问题描述】:

我什至不知道如何问这个问题。

我有一个宏,它为T 类型创建IsEnum[T] 的实例。

我正在对其进行测试,并希望确保未找到未密封类型的隐式,或者通常不满足枚举的要求。

所以我创建了这个方法来测试

    def enumOf[T](implicit isEnum:IsEnum[T] = null) = isEnum

然后我确保enumOf[NotAnEnum] == null

但是,它在编译时失败了。

一件事是宏错误。另一件事是宏只是不适用于给定案例。创建宏时如何区分?

编辑:我使用过c.abortc.error,两者的结果相同。

【问题讨论】:

  • @Pᴇʜ (offtopic) 你为什么删除标签macros

标签: scala implicit scala-macros


【解决方案1】:

听起来你没有让你的宏实现类型类IsEnum whitebox。通常隐式宏应该是白盒。

import scala.language.experimental.macros
import scala.reflect.macros.whitebox

trait IsEnum[T]
object IsEnum {
  implicit def mkIsEnum[T]: IsEnum[T] = macro mkIsEnumImpl[T]
  def mkIsEnumImpl[T: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
    import c.universe._
    val typ = weakTypeOf[T]
    val classSymbol = typ.typeSymbol.asClass
    if (!classSymbol.isTrait || !classSymbol.isSealed) c.abort(c.enclosingPosition, s"$typ must be sealed trait")
    val symbols = classSymbol.knownDirectSubclasses
    symbols.collectFirst {
      case symbol if !symbol.isModuleClass || !symbol.asClass.isCaseClass =>
        c.abort(c.enclosingPosition, s"${symbol.asClass.toType} must be case object")
    }
    q"new IsEnum[$typ] {}"
  }
}

def enumOf[T](implicit isEnum: IsEnum[T] = null) = isEnum

用法:

sealed trait A
object A {
  case object B extends A
  case object C extends A
  case class D() extends A
}
enumOf[A] //null

sealed trait A
object A {
  case object B extends A
  case object C extends A
  class D extends A
}
enumOf[A] //null

sealed trait A
object A {
  case object B extends A
  object C extends A
}
enumOf[A] //null

trait A
object A {
  case object B extends A
  case object C extends A
}
enumOf[A] //null

sealed trait A
object A {
  case object B extends A
  case object C extends A
}
enumOf[A] //App$$anon$1@47f37ef1

宏的运行时间是主代码的编译时间。如果黑盒宏(甚至是隐式黑盒宏)抛出异常,则在编译主代码期间将是编译错误。如果白盒隐式宏抛出异常,则在编译主代码期间,隐式将从候选者中静默删除。

https://docs.scala-lang.org/overviews/macros/blackbox-whitebox.html

【讨论】:

  • 您在我的最后两个问题中帮了我很多忙!这是非常非常有帮助的!而且很奇怪!
猜你喜欢
  • 2012-04-30
  • 2017-06-17
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
  • 1970-01-01
  • 2012-09-27
  • 2021-08-26
  • 1970-01-01
相关资源
最近更新 更多