【问题标题】:Scala macro-based annotation reuseScala 基于宏的注解重用
【发布时间】:2019-11-21 02:51:57
【问题描述】:

考虑一个基于 Scala 宏的注解,例如来自 macmemo@memoise。注释需要两个参数:最大缓存大小和生存时间,例如,

@memoize(maxSize = 20000, expiresAfter = 2 hours)

假设您要创建一个等效于@memoize(maxSize = Int.MaxValue, expiresAfter = 100 days)@cacheall 注释,以减少样板文件并具有单点参数化。

这种类型的重用是否有标准模式?很明显,

class cacheall extends memoize(Int.MaxValue, 100 days)

由于宏中的编译时参数解析而无法工作。

【问题讨论】:

    标签: scala annotations scala-macros scala-macro-paradise


    【解决方案1】:

    标准模式是让你的注解变成一个宏注解,被扩展的注解打开必要的注解和必要的参数。

    import scala.annotation.StaticAnnotation
    import scala.language.experimental.macros
    import scala.reflect.macros.blackbox
    
    class cacheall extends StaticAnnotation {
      def macroTransform(annottees: Any*): Any = macro cacheallMacro.impl
    }
    
    object cacheallMacro {
      def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = {
        import c.universe._
    
        val memoize = q"""
          new _root_.com.softwaremill.macmemo.memoize(
            _root_.scala.Int.MaxValue, {
              import _root_.scala.concurrent.duration._
              100.days 
          })"""
    
        annottees match {
          case q"${mods: Modifiers} def $tname[..$tparams](...$paramss): $tpt = $expr" :: _ =>
            q"${mods.mapAnnotations(memoize :: _)} def $tname[..$tparams](...$paramss): $tpt = $expr"
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多