gpt4 book ai didi

generics - 在 Scala 参数化(泛型)类型错误中使用 Guava 的简单缓存管理器

转载 作者:行者123 更新时间:2023-12-03 23:32:38 25 4
gpt4 key购买 nike

我对 Scala 还很陌生,但仍然不太了解泛型。因此,我无法弄清楚为什么编译器会因为类型不匹配错误而讨厌我。

我正在使用 Google 的 Guava 库来创建一些简单的缓存,表示为 Scala 的 ConcurrentMap。我想使用另一个缓存名称映射到 ConcurrentMap(缓存)来跟踪创建的缓存。这是我到目前为止编译但缺少缓存跟踪的内容(我已经注释掉了失败的位):

import scala.collection.mutable.ConcurrentMap

trait CacheManager {

def getCache[V <: AnyRef](
cacheName: String,
cacheListener: Option[CacheListener] = None): ConcurrentMap[String, V]

}


import scala.collection.JavaConversions._
import com.google.common.collect.MapMaker
import java.util.concurrent.{ConcurrentMap => JConcurrentMap, TimeUnit}
import org.slf4j.LoggerFactory
import com.google.common.cache.{RemovalNotification, RemovalListener, CacheBuilder}
import scala.collection.mutable.ConcurrentMap

class LocalCacheManager extends CacheManager {

private val logger = LoggerFactory.getLogger(classOf[LocalCacheManager])


private val caches /*: ConcurrentMap[String, ConcurrentMap[String, _ <: AnyRef]]*/ =
asScalaConcurrentMap[String, ConcurrentMap[String, _ <: AnyRef]](
new MapMaker().concurrencyLevel(4).makeMap[String, ConcurrentMap[String, _ <: AnyRef]]())

def getCache[V <: AnyRef](cacheName: String, cacheListener: Option[CacheListener] = None) = {
// caches.getOrElseUpdate(cacheName, {
val cache = CacheBuilder.newBuilder()
.concurrencyLevel(4)
.softValues()
.expireAfterAccess(30, TimeUnit.MINUTES)
.build[String, V]()
asScalaConcurrentMap[String, V](cache.asMap())
// })
}
}

基本上,如果我尝试将 Guava 缓存添加到缓存(通过注释掉的 caches.getOrElseUpdate),那么编译器会提示以下内容:
error: type mismatch;
found : scala.collection.mutable.ConcurrentMap[String,_$1] where type _$1 <: AnyRef
required: scala.collection.mutable.ConcurrentMap[String,V]
caches.getOrElseUpdate(cacheName, {

最佳答案

由于您在检索缓存时提供类型信息,因此没有必要尝试和维护通配符类型。将值键入到 AnyRef 然后在最后键入到 V 要简单得多。以下编译并应该有所帮助。此外,没有必要直接调用 asScalaConcurrentMap 因为它很好......隐式。

import scala.collection.JavaConversions._
import com.google.common.collect.MapMaker
import java.util.concurrent.TimeUnit
import com.google.common.cache.CacheBuilder
import scala.collection.mutable.ConcurrentMap

trait CacheListener // not sure what this is doing yet.

trait CacheManager {

def getCache[V <: AnyRef](
cacheName: String,
cacheListener: Option[CacheListener] = None): ConcurrentMap[String, V]

}

class LocalCacheManager extends CacheManager {
private val caches: ConcurrentMap[String, ConcurrentMap[String, AnyRef]] =
new MapMaker().concurrencyLevel(4).makeMap[String, ConcurrentMap[String, AnyRef]]()
def getCache[V <: AnyRef](cacheName: String, cacheListener: Option[CacheListener] = None) =
caches.getOrElseUpdate(cacheName, {
CacheBuilder.newBuilder()
.concurrencyLevel(4)
.softValues()
.expireAfterAccess(30, TimeUnit.MINUTES)
.asInstanceOf[CacheBuilder[String, AnyRef ]]
.build[String, AnyRef ]()
.asMap()
}).asInstanceOf[ConcurrentMap[String, V]]
}

关于generics - 在 Scala 参数化(泛型)类型错误中使用 Guava 的简单缓存管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8913379/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com