【问题标题】:Caching implicit resolution缓存隐式解析
【发布时间】:2015-12-21 15:38:00
【问题描述】:

为了减少我的项目的编译时间,我正在缓存通过隐式查找解析的某些类型类。不过这看起来有些麻烦,因为直接的实现不起作用:

scala> implicit val x: String = implicitly[String]
x: String = null

隐式查找将其自己的未初始化定义视为有效实现。 lazy val 会无限递归地破坏堆栈。因此,我目前正在以这种方式处理它:

implicit val x: String = cache.x

object cache {
   val x: String = implicitly[String]
}

但这使得它过于复杂,并且缓存定义不能轻易使用其他缓存类型类(因为它们不是隐式的)。

此外,不幸的是,将值本身隐藏在作用域中不起作用。

scala> :pas
// Entering paste mode (ctrl-D to finish)

object scope {
    implicit val x: String = {
        import scope.{ x => _ }
        implicitly[String]
    }
}

// Exiting paste mode, now interpreting.

defined object scope

scala> scope.x
res0: String = null

有没有更优雅的方式来实现隐式分辨率缓存?

【问题讨论】:

  • @Taig 你看过Shapeless 的cachedImplicit 宏吗​​? very similar 你正在做的事情。
  • @TravisBrown 这正是我一直在寻找(并暗中希望)的。我的谷歌查询没有遇到它。如果你把你的评论变成一个答案,我很乐意接受。

标签: scala scala-implicits


【解决方案1】:

Shapeless 提供了一个带有an implementationcachedImplicit 宏,这与您的非常相似(它使用阴影来避免递归,而且它是一个宏这一事实意味着使用可以更简洁)。

需要注意some limitations,您可能不想为这个单一方法承担新的依赖关系,但实现非常简洁,至少是一个很好的起点。

【讨论】:

    【解决方案2】:

    只是为了完整起见:接受的答案中的无形宏以我没有想到的方式掩盖了它自己的定义。因此,我的特殊问题可以这样解决:

    implicit val x: String = {
        def x = ???
        implicitly[String]
    }
    

    【讨论】:

      猜你喜欢
      • 2019-06-21
      • 1970-01-01
      • 2016-06-18
      • 1970-01-01
      • 1970-01-01
      • 2014-02-20
      • 2021-05-02
      • 1970-01-01
      • 2019-12-24
      相关资源
      最近更新 更多