缓存隐式解析 [英] Caching implicit resolution
问题描述
为了减少项目的编译时间,我正在缓存某些由隐式查找解决的类型类.不过,这看起来有些麻烦,因为直接实现无法正常工作:
To reduce compile times of my project, I'm caching certain type classes that are resolved by implicit lookups. This appears somewhat cumbersome though, because the straight forward implementation does not work:
scala> implicit val x: String = implicitly[String]
x: String = null
隐式查找将其自己的未初始化定义视为有效实现. lazy val
将无限递归地炸毁堆栈.因此,我目前正在以这种方式处理它:
The implicit lookup considers its own, uninitialized definition as a valid implementation. A lazy val
would blow the stack with infinite recursion. Therefore I'm currently handling it in this fashion:
implicit val x: String = cache.x
object cache {
val x: String = implicitly[String]
}
但是,这使其变得过于复杂,并且缓存定义不能轻松利用其他缓存类型类(因为它们不是隐式的).
But this makes it overly complicated, and the cache-definitions can not make use of other cached type classes easily (since they are not implicit).
此外,不幸的是,将值本身隐藏在范围之外确实行不通.
Also, hiding the value itself from scope does unfortunately not work.
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
是否有更优雅的方法来实现隐式分辨率缓存?
Is there a more elegant way to achieve an implicit resolution cache?
推荐答案
Shapeless 提供了带有
Shapeless provides a cachedImplicit
macro with an implementation that's very similar to yours (it uses shadowing to avoid the recursion, and the fact that it's a macro means the usage can be cleaner).
有有一些局限性要注意,您可能不想对它进行新的依赖这种单一方法,但是实现起来非常简洁,并且至少是一个很好的起点.
There are some limitations to be aware of, and you may not want to take on a new dependency for this single method, but the implementation is pretty concise, and it's at least a good starting point.
这篇关于缓存隐式解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!