Scala宏:类型化(又称typechecked)与无类型树之间有什么区别?
我正在开始使用
scala宏,它们非常棒,但我遇到了类型(又称typechecked)和无类型树之间的区别.
例如,由于某些原因,您不能使用类型检查的树来调用c.eval.我在scala宏文档中找不到关于这个“typechecked”的文档(我知道他们仍在努力,这可能是某些需要添加的东西). 对树进行类型检查是什么意思?为什么它们如此不同,显然c.eval无法处理类型检查的树(相反会对我更有意义). 我猜这可能是编译器101,但是我没有采取这个方法:( 解决方法
理论部分
一旦我们在2.10的编译时/运行时反映中暴露了内部编译器数据结构,这就是scalac的架构特性,开始泄露到公共API中. 粗略地说,scalac的前端由一个解析器和一个打击者组成,它们都与树木一起工作并产生树木.然而,这些树的属性是完全不同的,它来自于解析器产生的树是未归属的(其符号字段设置为NoSymbol,并且它们的tpe字段设置为null),而由typer生成的树被归因. 现在你可能想知道这可以做出什么样的区别,因为它只是符号和tpe,对吧?然而,在scalac中,它不仅仅是这样.为了做好自己的工作,老板改变了它正在处理的AST的结构,摧毁了一些原始的树,并生产了一些合成树.不幸的是,有时这些转换是不可逆转的,这意味着如果一个类型检查树,然后擦除所有分配的属性,则生成的树不再有意义了(https://issues.scala-lang.org/browse/SI-5464). 好的,但为什么会想要删除(或者在scalac的说法,重置,如resetLocalAttrs或resetAllAttrs)属性的类型检查树?那么这个必要性来源于另一个实现细节 – 符号及其所有者链.就在几天之前,我已经写了关于scala内部的内容的一些细节:https://groups.google.com/d/msg/scala-internals/rIyJ4yHdPDU/qS-7DreEbCwJ,但是简而言之,你不能在一些词汇上下文中键入一个树,然后简单地在不同的词汇语境中使用它(这就是基本上需要c.eval). 所以,总结一下在scalac树管理中的最新技术: >非类型树(也称为解析器树或未归因树)与类型树(也称为树木树,类型树或属性树)观察不同, 所以,你可以看到,我们的树是相当反复无常的,这给Scala的元编程带来了很大的复杂性. 然而,好消息是,这种复杂性并不是源于编译器101的一些根本的好原因所在.所有的复杂性都是偶然的,我们计划逐步驱逐它,直到完全消失. https://groups.google.com/forum/#!topic/scala-internals/TtCTPlj_qcQ(也发布了几天前)是朝这个方向迈出的第一步.敬请关注今年也可能到达的其他美食! 实际部分 通过详细阐述所有的细节,并暗示无神秘的情况,当没有任何工作完全吓倒你之后,我想注意到,通常一个人不需要知道这种东西,当使用宏.很多时候,两种无类型的树(手动构造的AST,quasiquotes)和键入的树(宏参数)工作正常. 在这种情况下,当scalac想要一个特定的树风味时,它会告诉你像c.eval或有时在你的脸上崩溃(RefChecks,LambdaLift和GenICode崩溃是巨大的指标,树在宏扩展期间混合 – 在这些情况下使用resetLocalAttrs如https://groups.google.com/forum/#!msg/scala-internals/rIyJ4yHdPDU/qS-7DreEbCwJ所述).解决这个问题是我的首要任务,我正在努力工作.这可能会发生,修复将使它成为2.11.0,这个答案将很快过时:) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |