gpt4 book ai didi

scala - 在 Scala 2.10 中使用带有宏的附件

转载 作者:行者123 更新时间:2023-12-04 16:10:56 25 4
gpt4 key购买 nike

更新:我怀疑我想要的可能是不可能的,我写了一篇博客文章,其中包含我的推理(和一些替代方案)here .我很高兴被告知我错了。

假设我想使用带有宏实现的工厂方法创建特征的实例。此方法将把资源的路径作为参数,宏将读取该路径并将其解析(在编译时)到从字符串到字符串的映射中。

这部分相当简单。现在假设我想将结果映射与我正在创建的实例相关联,以便我可以在涉及该实例的后续宏调用中使用它。

我非常不希望 map 成为实例的成员,或者在运行时以任何形式存在。我也不想多次解析相同的资源。这是我的目标类型的草图:

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 的那种事情。旨在帮助(感谢 Eugene Burmako for the pointer ),我有一个基于附件的实现,允许我编写以下内容:
Foo("whatever.txt").lookup("x")

哪里 apply_impl将 map 附加到树和 lookup_impl从同一棵树上读取该附件,它将其视为其前缀。不幸的是,这或多或少是无用的,因为它在 foo.lookup("x") 中不起作用。在这种情况下,前缀树只是变量 foo .

(请注意,在我的实际用例中 Foo 扩展了 Dynamic ,并且我试图为 selectDynamic 而不是 lookup 提供宏实现,但这不应该在这里相关 - 我感兴趣一般情况。)

有什么方法可以使用附件来获得我想要的东西吗?还有其他更合适的方法吗?

最佳答案

更新 我应该在摆弄之后再次阅读这个问题...... :(我刚刚复制了你所拥有的。

我想你就在那里。这对我有用:

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)))

}

}

关于scala - 在 Scala 2.10 中使用带有宏的附件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17580781/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com