- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在使用 Scala 宏,并在宏中包含以下代码:
val fieldMemberType = fieldMember.typeSignatureIn(objectType) match {
case NullaryMethodType(tpe) => tpe
case _ => doesntCompile(s"$propertyName isn't a field, it must be another thing")
}
reify{
new TypeBuilder() {
type fieldType = fieldMemberType.type
}
}
如您所见,我已成功获取 c.universe.Type fieldMemberType
。这表示对象中某个字段的类型。一旦我明白了,我想在 reify 中创建一个新的 TypeBuilder
对象。 TypeBuilder
是一个带有抽象参数的抽象类。这个抽象参数是fieldType
。我希望这个 fieldType
是我之前找到的类型。
运行此处显示的代码会返回fieldMemberType not found
。有什么方法可以让 fieldMemberType
在 reify 子句中工作吗?
最佳答案
问题在于,您传递给 reify
的代码本质上将逐字放置在宏展开的位置,而 fieldMemberType
不会在那里表达任何意思。
在某些情况下,您可以使用 splice
将宏扩展时的表达式隐藏到您正在具体化的代码中。例如,如果我们尝试创建此特征的实例:
trait Foo { def i: Int }
并且在宏扩展时有这个变量:
val myInt = 10
我们可以编写以下内容:
reify { new Foo { def i = c.literal(myInt).splice } }
这在这里不起作用,这意味着您将不得不忘记漂亮的小reify
并手动写出AST。不幸的是,你会发现这种情况经常发生。我的标准方法是启动一个新的 REPL 并输入如下内容:
import scala.reflect.runtime.universe._
trait TypeBuilder { type fieldType }
showRaw(reify(new TypeBuilder { type fieldType = String }))
这将输出几行 AST,然后您可以将其剪切并粘贴到宏定义中作为起点。然后你摆弄它,替换如下内容:
Ident(TypeBuilder)
这样:
Ident(newTypeName("TypeBuilder"))
以及 FINAL
和 Flag.FINAL
,依此类推。我希望 AST 类型的 toString 方法与构建它们所需的代码更准确地对应,但您很快就会知道需要更改什么。你最终会得到这样的结果:
c.Expr(
Block(
ClassDef(
Modifiers(Flag.FINAL),
anon,
Nil,
Template(
Ident(newTypeName("TypeBuilder")) :: Nil,
emptyValDef,
List(
constructor(c),
TypeDef(
Modifiers(),
newTypeName("fieldType"),
Nil,
TypeTree(fieldMemberType)
)
)
)
),
Apply(Select(New(Ident(anon)), nme.CONSTRUCTOR), Nil)
)
)
其中 anon
是您预先为匿名类创建的类型名称,constructor
是我用来使这种事情变得更简单的一种便捷方法不那么丑陋(你可以在 this complete working example 的末尾找到它的定义)。
现在,如果我们将这个表达式包装在 this 之类的内容中,我们可以这样写:
scala> TypeMemberExample.builderWithType[String]
res0: TypeBuilder{type fieldType = String} = $1$$1@fb3f1f3
所以它有效。我们采用了 c.universe.Type
(我从 builderWithType
上类型参数的 WeakTypeTag
中获取的,但它会起作用与任何旧的 Type
完全相同),并用它来定义 TypeBuilder
特征的类型成员。
关于scala - 如何在 reify 子句中使用 Scala 宏中计算的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13795490/
下面的测试类,通过。 class SimpleClassTest { private inline fun anyObject(): T { return Mockito.a
我需要获取 lambda 函数实现的 AST。我被卡住了,因为 reify 对论点起作用,而不是对它的值(value)起作用。 val x = (a: Int) => println("a") val
基于 this comment关于具体化, It acts like @property, except that the function is only ever called once; aft
我有一些这样的代码: {-# LANGUAGE AllowAmbiguousTypes #-} module Foo where import Data.Proxy class Foo x y cla
当使用reify时在 Clojure 中,如何为构造函数提供表达式? 或者,如何将参数传递给基类构造函数? 最佳答案 您不能使用reify来子类化和实例化类——它仅适用于协议(protocol)和接口
我尝试阅读论文( http://www.ittc.ku.edu/csdl/fpg/sites/default/files/Gill-09-TypeSafeReification.pdf )并设法具体化
是否有可能做到 reify在 GHCi 中? 当我使用“runQ”尝试它时,它提示“无法在 IO monad 中进行具体化”。 >>> runQ (reify ''Bool) Template Has
为什么我们需要Control.Lens.Reified ?是否有某种原因导致我无法将 Lens 直接放入容器中? reify 到底是什么意思? 最佳答案 我们需要具体化的镜头,因为 Haskell 的
我正在尝试围绕如下所示的 Java API 编写 Clojure 层: public class Executor { public interface ExecutorJob { pub
我在 Pyramid tutorial for UX design 中看到了.我无法弄清楚这个装饰器到底是什么。 我看到其用法的示例代码。 def __init__(self, request):
我试图理解 reified 关键字的用途,显然是 it's allowing us to do reflection on generics . 但是,当我将其省略时,它也可以正常工作。任何人愿意解释
我一直在使用 Scala 宏,并在宏中包含以下代码: val fieldMemberType = fieldMember.typeSignatureIn(objectType) match {
为什么我应该在 clojure 中使用 Reify 而不是代理? 最佳答案 reify 的方法体是词法闭包,可以引用周围的局部作用域。 reify 与 proxy 的不同之处在于: 仅支持协议(pro
我编写了一些代码,以使用“DefineTypeGeneric”类检测类型模型数据。 主类 fun main() { val list = ArrayList() list.add("K
实际上,主要问题仍然是 Kotlin 中的类没有具体化的类型参数。但这就是为什么在这种特定情况下这困扰我的原因: 假设您有一个包装类 Wrapper接受一个字符串 content和一个类(class)
我在有关 haskell 和函数式编程的博客中读了很多这个术语(特别是 sigfpe's blog ),但我不知道它的含义。大多数时候我都不知道,但如果我知道的话,我可能会更好地理解这些文本。谷歌没有
我有一个仅发出事件的 java 接口(interface),我正在尝试在 Clojure 中实现它。 Java接口(interface)是这样的(现实中还有很多其他方法): public interf
我正在尝试编写一个断言函数来检查给定对象是否属于 T 类型: @UseExperimental(ExperimentalContracts::class) inline fun assertIsIn
我真的可以用你的帮助来解释这个功能。 我有一个包含 2 个字符串值、一个国家名称和一个货币的国家枚举。练习是使用 2 个字符串输入,检查枚举是否有国家,然后比较它们的货币,相应地返回 true 或 f
我正在寻找 -print 或 javap 的替代方案来了解编译器在 Scala 中执行的操作。有了新的反射/宏库,reify 似乎是一个很好的候选者,如 Retronym 的 macrocosm 所示
我是一名优秀的程序员,十分优秀!