使用谷歌番石榴的CacheBuilder的scala 2.10类型不匹配 [英] scala 2.10 type mismatch using google guava's CacheBuilder

查看:189
本文介绍了使用谷歌番石榴的CacheBuilder的scala 2.10类型不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Scala 2.10.1中的一些实体编写通用缓存.现在,由于scala生态系统中没有太多选项,因此我正在使用Google Guava的CacheBuilder.

I am writing a generic cache for a few of my entities in scala 2.10.1. For now, I am using google Guava's CacheBuilder since there aren't many options in scala ecosystem.

代码:

trait CachedEntity[E <: KeyedEntity[K],K] {

  def lookup(id:K):E

  def getElem(id:K):Option[E] = Try(elemCache.get(id)).toOption

  val elemCache = CacheBuilder.newBuilder().maximumSize(10).expireAfterWrite(1,TimeUnit.MINUTES).build(
    new CacheLoader[K,E] {
      def load(key:K) = {
        println("Looking Up key:" + key + "in Class:" + this.getClass.getName)
        lookup(key)
      }
    }
  )
}
trait LongKeyed[E<: KeyedEntity[Long],Long] extends CachedEntity[E,Long]

但是,sbt会引发错误:

However, sbt throws error:

[error] KEHCaching.scala:16: type mismatch;
[error]  found   : id.type (with underlying type K)
[error]  required: Object with K
[error]   def getElem(id:K):Option[E] = Try(elemCache.get(id)).toOption
[error]                                                   ^
[error] one error found

有什么想法吗?即使我这样添加K<:Object:

Any ideas? Even if I add K<:Object like this:

trait CachedEntity[E <: KeyedEntity[K],K <:Object] {

我收到此错误

[error] KEHCaching.scala:27: type arguments [E,Long] do not conform to trait CachedEntity's type parameter bounds [E <: org.squeryl.KeyedEntity[K],K <: Object]
[error] trait LongKeyed[E<: KeyedEntity[Long],Long] extends CachedEntity[E,Long]
[error]                                                     ^
[error] one error found

推荐答案

如果您不介意一些丑陋的转换,则可以使其正常工作.主要问题是CacheBuilder上的build函数返回与类型[Object,Object]绑定的缓存.在Scala中,AnyVal不是从Object派生的,因此它将不起作用.但是我模拟了以下代码示例,以展示如何通过一些难看的转换来解决此限制:

If you don't mind a little ugly cast, you can get this to work. The main issue is that the build function on CacheBuilder returns a cache tied to types [Object,Object]. In Scala, the AnyVal is not derived from Object, so it won't work. But I mocked up the following code sample to show how you can work around this limitation with a little ugly casting:

trait CachedEntity[E <: KeyedEntity[K], K] {

  def lookup(id:K):E

  def getElem(id:K):Option[E] = Try(elemCache.get(id)).toOption

  val elemCache = CacheBuilder.newBuilder().build(
    new CacheLoader[K,E] {
      def load(key:K) = {
        println("Looking Up key:" + key + "in Class:" + this.getClass.getName)
        lookup(key)
     }
    }
  ).asInstanceOf[LoadingCache[K,E]]
}

trait LongKeyed[E<: KeyedEntity[Long]] extends CachedEntity[E,Long]

case class MyEntity(id:Long, value:String) extends KeyedEntity[Long]

class MyEntityCache extends LongKeyed[MyEntity]{
  def lookup(id:Long) = MyEntity(id, "foo") 
}

object CachedEntityTest{
  def main(args: Array[String]) {
    val cache = new MyEntityCache
    val entity = cache.getElem(1)
    println(entity)
  }
}

//Faking this for purposes of code sample...
trait KeyedEntity[K]

这篇关于使用谷歌番石榴的CacheBuilder的scala 2.10类型不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆