加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-16 18:46:49 所属栏目:安全 来源:网络整理
导读:更新:我怀疑我想要的可能是不可能的,我已经用我的推理(以及一些替代方案)写了一篇博客文章 here.我很高兴被告知我错了. 假设我想使用带有宏实现的工厂方法创建特征实例.此方法将参数作为资源的路径,宏将读取并在编译时将其解析为从字符串到字符串的映射. 那
更新:我怀疑我想要的可能是不可能的,我已经用我的推理(以及一些替代方案)写了一篇博客文章 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)))

  }

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读