问题标签 [scala-quasiquotes]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
393 浏览

scala - scala quasiquotes:比较类型

作为概述,我尝试使用反射从 Cassandra Java Row 动态创建案例类的构造函数,以找到案例类的主构造函数,然后尝试从 Cassandra Row 中提取值。

具体来说,我想支持案例类中的选项作为行中的可选字段,这样 case class Person(name: String, age: Option[Int]) 如果行有名称和年龄,或者只是名称(并为年龄填写无),它将成功填充。

为此,我关注了这篇非常有用的博客文章,它在案例类和地图之间实现了类似的目标。

然而,我似乎被困在试图巩固从案例类中反射性地提取类型的动态特性和准引号的编译时特性。举个例子:

我有一个类型fieldType,它可以是本机类型或本机类型的选项。如果是 Option,我想传递returnType.typeArgs.head给我的 quasiquote 构造,以便它可以从 Row 中提取参数化类型,如果不是 Option,我将传递 returnType。

if (fieldType <:< typeOf[Option[_]]) q"r.getAs[${returnType.typeArgs.head}]($fieldName)" else q"r.as[$returnType]($fieldName)"

(假设 r 是 Cassandra Rowas并且getAs存在于该行)

当我尝试编译它时,我收到一个错误,说它不知道如何处理r.as[Option[String]]。这对我来说在概念上是有意义的,因为编译器无法知道运行时比较将以哪种方式解决,因此需要检查这两种情况。

那么我该如何进行这种类型检查呢?如果我可以比较准引用中的类型fieldType和类型typeOf[Option[_]],它可能会停止抱怨,但我不知道如何比较准引用中的类型,我什至不确定这是否可能。如果我可以在准引号中提取 Option 的参数化类型,它可能会停止抱怨,但我也无法弄清楚。

抱歉,我对 Scala 很陌生,目前这些东西对我来说非常混乱和深奥。如果您想更仔细地查看我在做什么,我有一个回购:https://github.com/thurstonsand/scala-cass/blob/master/src/main/scala/com/weather/scalacass/ScalaCass。 scala ,其中有趣的部分是 ScalaCass.CaseClassRealizer,我正在 CaseClassUnitTests 中对其进行测试。

0 投票
2 回答
2079 浏览

scala - Scala:为案例类动态生成匹配子句

我想在一组“条件动作”规则中使用 Scala 模式匹配的强大功能。这些规则不是事先知道的,而是根据一些复杂的标准在运行时生成的。算法生成机制可以被认为是完全独立的,不是这个问题的一部分,它涉及如何通过 Scala 反射/准引用来表达这一点。

具体来说,我希望case v0@x(v1,_,v2): X => f(v1,v2)在运行时生成(一般形式的)案例定义。

toolBox.parse(str)对于在运行时生成的某些字符串,大概可以做到这一点。但是,如果可能的话,似乎需要包含比这更大程度的类型安全:

Term,Var(name: Char),Lit(value:Int),Group(a: Term,b: Term,c: Term)更具体地说,我希望case defs 与Terms ( )的密封case 类层次结构相匹配。

例如,生成的案例 def 通常会返回一些无函数、部分或全部 v0、v1、v2:

我正在尝试按照此处给出的 case defs 的 quasiquotes 描述进行操作,但语法相当令人费解(并且 Scala 2.11 的 eclipse 拒绝向我显示类型),所以下面是我所得到的. 我的具体问题嵌入在代码中:

0 投票
2 回答
347 浏览

scala - Scala quasiquote 宏示例损坏 - 类型签名关闭

我从“Programming Scala”(第 2 版)一书中获取了这个 Scala quasiquote 示例

我收到此错误:https ://issues.scala-lang.org/browse/SI-9711

类型推断显示“Trees#Tree”,但类型推断已关闭。

^ 文档应该是不言自明的。类型推断是 Tree#Tree,但在示例代码中添加“:Tree#Tree”会导致编译出错:

我在 IntelliJ 中得到“类型不匹配,预期的树,实际的树#树”

0 投票
2 回答
248 浏览

scala - Scala 宏可以在类中定义(作为该类的方法)吗?

我的 Scala 断言库需要 Scala 宏(reify、quasiquote、macro impl)。


我希望能够做到这一点:

或者像这样:


可以在隐式类中定义 Scala 宏吗?

0 投票
1 回答
298 浏览

scala - 具有新标识符的 scala 宏

我有一个宏,我想用它来记录执行一个可能返回有用的块所需的时间。因此,如果我有类似的东西, val y = f(x)我将更改为val y = Timed(f(x))获取在日志中执行该功能所需的时间。

我几乎有我想要的,但是当使用新的术语名称来避免名称冲突时,例如在 t0 和 t1 之间,我收到一个错误:

如何让这些freshTermNames 与准引号一起使用?

0 投票
1 回答
1396 浏览

scala - 使用 Scala quasiquotes 提升字符串变量

这是我面临的问题的简化版本,但根本问题仍然存在。调用宏后,我想动态生成案例类。我能够从宏调用等中检索参数。我遇到的问题是尝试在准引号中使用字符串变量。我基本上想要以下内容:

但是,不会生成案例类。现在我知道如果我将 toGen 更改为 q"case class Foo()" 它将起作用,但是 toGen 是一个字符串,我将在其他一些返回字符串的处理之后生成,所以我不能这样做。像这样编译它并手动查看 toReturn 的值,我得到以下信息:

字符串 toGen 只是简单地粘贴在引号中,这意味着不会生成案例类。

我一直在寻找类似的问题,但在任何地方都找不到这个例子。如何在准引号内取消引用字符串变量的双引号?

0 投票
1 回答
248 浏览

scala - Scala“反射工具箱因未解析的自由类型而失败”

第一次尝试使用 quasiquotes 来生成新的案例类:

Produce.A() 的结果:

我是一个

我还活着

res0: A = 儿子()

Produce[A]() 的结果:

scala.tools.reflect.ToolBoxError:反射工具箱因未解析的自由类型变量而失败:T 在 :32:13 中由 apply 定义,您是否忘记对 reifee 外部的类型参数使用 TypeTag 注释?如果您在跟踪自由类型变量时遇到问题,请考虑在 scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.verify(ToolBoxFactory.scala:82) 在 scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal 使用 -Xlog-free-types .compile(ToolBoxFactory.scala:208) at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$$anonfun$compile$2.apply(ToolBoxFactory.scala:429) at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$$anonfun$compile$2 scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$withCompilerApi$.liftedTree2$1(ToolBoxFactory.scala:355) 的 .apply(ToolBoxFactory.scala:422)。

0 投票
1 回答
688 浏览

scala - Scala 宏注解 - 带类型参数的案例类

我正在尝试为案例类编写一个简单的宏注释,它向伴随对象添加一个方法。问题是新方法必须考虑带注释的案例类的类型参数。

这是我需要通过的测试

这是我为完成此任务而编写的代码

据我了解的问题是,当我尝试类型参数列表提升到生成的语法树中时,它们不会被识别为与原始树中相同的类型参数。

所以我关注的是宏的这一部分

原始语法树发出为

但编译器对此不满意

最终用例是生成涉及超过 1k 行代码的可缓存类型类的实例。非参数化版本已经可以工作了,这只是锦上添花。scalac 的底层有些东西我不明白,但我想。非常感谢您花时间阅读本文。

我正在使用带有宏天堂 2.1.0的 Scala 2.11.8

0 投票
0 回答
298 浏览

scala - Scala宏生成具有抽象字段的特征依赖注入的新类实例

更新:修改代码以使用宏注释,但仍然缺少一些东西

以下代码有效(下面的问题):


我希望能够运行以下内容:

我试过这样做:

但是,这不起作用。

0 投票
1 回答
55 浏览

scala - 带准引号的可变长度“选择”

使用 Scala 的 quasiquotes,您可以轻松构建选择树,如下所示:

我的问题是,如果要从中选择的事物列表(a、b、...等)是可变长度的(因此在需要拼接的变量中),我该怎么做?

我希望举重会起作用(例如tq"""..${List("a","b","MyObj")}""",但它没有。或者甚至可能是这个tq"""${List("a","b","MyObj").mkString(".")}""",但没有运气。

有没有办法用准引号来支持这一点?还是在这种情况下我只需要手动构建选择树?