缓存隐式解决方案

时间:2015-12-21 15:38:01

标签: scala scala-implicits

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

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

是否有更优雅的方法来实现隐式解析缓存?

2 个答案:

答案 0 :(得分:10)

Shapeless提供了一个cachedImplicitan implementation,它与你的非常相似(它使用阴影来避免递归,而且它是一个宏意味着使用可以更清晰)

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

答案 1 :(得分:3)

仅仅为了完整性:接受的答案中的无形宏以我没有提出的方式影响它自己的定义。因此,我的特殊问题可以通过这种方式解决:

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