scala 3:内联与引用(宏)

oymdgrw7  于 2021-07-14  发布在  Java
关注(0)|答案(1)|浏览(288)

最近我有一个在Scala3中编写宏的经验。我曾经 inline 对于简单函数和带引号的代码 scala.quoted 更复杂的操作。
似乎这两个特性都用编译时生成的代码替换了一些运行时代码,但是 inline 有一些限制。
它们之间有什么区别?为什么 inline 不能到处用引号代替代码吗?

xnifntxz

xnifntxz1#

热释光;博士 inline 是一种机制,它在编译时用函数调用的完整体替换函数调用(一种优化形式)。在scala中,它还用于编写宏,即在编译时计算的函数,可以操作ast scala代码。 scala.quoted 包含使用quasiquoting(一种简洁的表示法,可以让您轻松地操作scala语法树)和splicing(quasiquoting的逆运算符)运算符编写宏的函数。通常,它们一起用于创建编译时元编程。的确, inline 是使能机制和 scala.quoted 提供了一些操作和评估scala-ast的功能。当您不能在编译时推断某些东西(或者您想在运行时生成代码)时,您不能使用inline,您应该单独使用scala.quoted。
内联是一种用于内联代码而不是执行函数调用的机制。例如:

inline def foo : Int = 3
foo

变成了这样

inline def foo : Int = 3
3

其他语言(如kotlin)也引入了这种机制,但scala语言还有另一个相关特性:在内联扩展期间,编译器可以执行进一步的编译时操作来操纵内联输出过程。可以使用内联条件和内联匹配执行编译元编程的一种形式:

inline acceptString(value : String) : Boolean = inline match {
    case "name" => true
    case "other" => false
    case _ => error("error thrown at compile time"
}

如果您作为参数传递,则此代码(在编译时)会引发异常 "hello" 例如。
相反 scala.qouted 包含操作scala-ast:quoting(quasiquotes是一种简洁的表示法,可以轻松地操作scala语法树:)和splicing(quasiquote的逆运算符)的运算符。理论上,这些操作符可以在运行时(使用新的美味结构)和编译时(使用 inline ). 如这里所述,内联和引用之间的关系是:
就其本身而言,原则元编程看起来更像是运行时元编程的框架,而不是使用宏进行编译时元编程的框架。但是结合scala3的内联特性,它可以变成一个编译时系统。其思想是宏精化可以理解为宏库和引用程序的组合。
有时,您被迫使用运行时扩展,因为某些信息在编译时无法推断,或者您希望在运行时生成代码。因此,您可以使用报价进行运行时多阶段编程和美味的检查。
我希望我能给你一个更清晰的视角和有用的链接,让你更深入地探索这些引人入胜的主题。

相关问题