2013-04-24 6 views
4

Я пишу общий кэш для нескольких моих объектов в scala 2.10.1. На данный момент я использую google Guava CacheBuilder, поскольку в scala-экосистеме не так много вариантов.scala 2.10 несоответствие типа с использованием goache guava's CacheBuilder

Код:

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 броски ошибка:

[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, как это:

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 
+0

Было бы лучше, если бы фрагменты кода были синтаксически правильными. Два последовательных периода ('.') в вашем коде не могут быть скомпилированы. Кроме того, ваш код _suggests_, но не дает понять, что 'K' и' E' являются параметрами типа, связанными в какой-либо закрывающей конструкции. Можете ли вы исправить и заполнить фрагменты кода, чтобы люди реплицировали и изменяли ваш исходный код? –

+0

Извините за это. Обновлен код с помощью объявления класса. – adivis

ответ

1

Если вы не против немного некрасивый оттенок, вы можете получить эту работу. Основная проблема заключается в том, что функция build на CacheBuilder возвращает кеш, привязанный к типам [Object,Object]. В Scala AnyVal не является производным от Object, поэтому он не будет работать. Но я издевался до следующего кода, чтобы показать, как можно обойти это ограничение с небольшой уродливой литьей:

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] 
+0

Я сделал это и получил вторую ошибку. Обновлен вопрос, чтобы отразить то же самое. Я думаю, что если бы установить ограничения типа на <: Object, почти все anyvals запрещены, что не то, что я хочу. – adivis

2

CacheBuilder требует Object/AnyRef. Вы можете использовать java.lang.Long вместо scala.Long следующим образом; Scala автоматически поместит/распакуется.

import scala.util.Try 
import java.util.concurrent.TimeUnit 
import java.lang.{Long => JLong} 

trait KeyedEntity[K] 

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

    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[JLong]] extends CachedEntity[E,JLong] 
Смежные вопросы