11

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

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

隐式查找将其自己的未初始化定义视为有效实现。Alazy 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

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

4

2 回答 2

11

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

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

于 2015-12-21T17:49:19.617 回答
3

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

implicit val x: String = {
    def x = ???
    implicitly[String]
}
于 2015-12-22T15:40:15.453 回答