在Scala 2.10中使用带有宏的附件
更新:我怀疑我想要的可能是不可能的,我已经用我的推理(以及一些替代方案)写了一篇博客文章
here.我很高兴被告知我错了.
假设我想使用带有宏实现的工厂方法创建特征实例.此方法将参数作为资源的路径,宏将读取并在编译时将其解析为从字符串到字符串的映射. 那部分都相当简单.现在假设我想将结果映射与我正在创建的实例相关联,以便我可以在涉及该实例的后续宏调用中使用它. 我至关重要的是不希望地图成为实例的成员,或者在运行时以任何形式存在.我也不想多次解析同一个资源.这是我想要的那种东西的草图: import scala.language.experimental.macros import scala.reflect.macros.Context trait Foo { def lookup(key: String): String = macro Foo.lookup_impl } object Foo { def parseResource(path: String): Map[String,String] = ??? def apply(path: String): Foo = macro apply_impl def apply_impl(c: Context)(path: c.Expr[String]): c.Expr[Foo] = { import c.universe._ val m = path.tree match { case Literal(Constant(s: String)) => parseResource(s) } val tree = reify(new Foo {}).tree // Somehow associate the map with this tree here. c.Expr(tree) } def lookup_impl(c: Context)(key: c.Expr[String]): c.Expr[String] = /* Somehow read off the map and look up this key. */ ??? } 这似乎是attachments旨在帮助的东西(感谢the pointer the pointer),我有一个基于附件的实现,允许我编写以下内容: Foo("whatever.txt").lookup("x") 其中apply_impl将映射附加到树中,lookup_impl从同一个树中读取该附件,它将其视为其前缀.不幸的是,这或多或少是无用的,因为它在foo.lookup(“x”)情况下不起作用,其中前缀树只是变量foo. (请注意,在我的实际用例中,Foo扩展了Dynamic,我正在尝试为selectDynamic而不是查找提供宏实现,但这不应该与此相关 – 我对一般情况感兴趣.) 有什么方法可以使用附件来获得我想要的东西吗?还有其他方法更合适吗? 解决方法
更新我应该在摆弄后再次阅读这个问题…… :(我只是复制了你的内容.
你觉得你在那里.这对我有用: object Foo { // Attachment.get somehow needs a wrapper class. // Probably because of generics implicit class LookupMap(m: Map[String,String]) { def get(s: String) = m.get(s) } def parseResource(path: String): LookupMap = Map("test" -> "a") def apply_impl(c: Context)(path: c.Expr[String]): c.Expr[Foo] = { import c.universe._ val m = path.tree match { case Literal(Constant(s: String)) => parseResource(s) } val tree = reify(new Foo {}).tree.updateAttachment(m) c.Expr(tree) } def lookup_impl(c: Context { type PrefixType = Foo }) (key: c.Expr[String]): c.Expr[String] = { import c.universe._ val m = c.prefix.tree.attachments.get[LookupMap].get val s = key.tree match { case Literal(Constant(s: String)) => m.get(s).get } c.Expr(Literal(Constant(s))) } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |