加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 是否可以集成Cake-Pattern和Macros?

发布时间:2020-12-16 18:37:58 所属栏目:安全 来源:网络整理
导读:我必须在一个使用蛋糕模式的项目中集成一些宏.这种模式使我们能够避免数以万计的进口,以及其他优势,因此我们希望保留它.现在,我们正面临一些问题,我们已经在主干外测试了一些实验宏.首先,让我们展示一个名为Cake的虚拟系统: trait APiece { class A}trait B
我必须在一个使用蛋糕模式的项目中集成一些宏.这种模式使我们能够避免数以万计的进口,以及其他优势,因此我们希望保留它.现在,我们正面临一些问题,我们已经在主干外测试了一些实验宏.首先,让我们展示一个名为Cake的虚拟系统:

trait APiece {
  class A
}

trait BPiece { this: APiece => 
  def aMacro(a: A): Unit = () /* macro ??? */
}

trait CPiece { this: APiece with BPiece =>
  def aMacroInvoker = aMacro(new A)
}

class Cake { this: APiece with BPiece with CPiece => }

APiece定义了一个类,BPiece应该是一个使用APiece定义类的宏,最后,CPiece调用宏.我说BPiece应该是一个宏,因为我无法为它编写实现代码.我尝试了几种方法,但我总是崩溃以下错误:

"macro implementation must be in statically accessible object"

读取macros code可以猜测将宏封装在静态模块中是必要的.有没有办法部署使用系统结构的宏?

解决方法

幸运的是,您可以轻松解决问题.

但首先,让我来回顾一下.在第一个原型中,宏的定义如下:def macro aMacro(a:A):Unit = ….我们在准备SIP时遇到的一个重大突破是分离宏定义(宏的公共面)和宏实现(托管宏逻辑的树变换器).我花了一段时间才意识到它有多酷,但现在每次写宏观声明时我都会高兴得发光.

所以,回到你的问题.当然,宏实现必须是静态可访问的(否则,编译器将无法在编译期间加载和调用它们).但是宏定义没有这个限制,所以你可以像这样编写定义:

trait BPiece { this: APiece => 
  def aMacro(a: A): Unit = macro Macros.aMacro
}

从定义中引用的宏实现可以放入您希望的任何对象中,甚至可以放入不同的编译单元中.

唯一缺失的难题是我们将如何从实现中引用A,因为A是在蛋糕内定义的.最简单的方法是使aMacro通用并依赖于类型推断:

(更新:要使此示例在2.10.0-M7中工作,您需要将c.TypeTag替换为c.AbsTypeTag;要使此示例在2.10.0-RC1中工作,c.AbsTypeTag需要替换为c.WeakTypeTag )

trait BPiece { this: APiece =>
  def aMacro[A](a: A): Unit = macro Macros.aMacro[A]
}

object Macros {
  def aMacro[A: c.TypeTag](c: Context)(a: c.Expr[A]): c.Expr[Unit] = c.literalUnit
}

但是,这不会让你使用reify,因为对于宏实现,A只是一个没有任何成员的类型参数.如果你想要从宏中返回特定于蛋糕的东西,也会出现问题,但是当它们出现时让我们处理它们.如果需要,请提交后续问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读