我正在通过 scala 代码使用 Google Guava。当我尝试使用 Int 作为键类型时出现问题,如示例所示:
CacheBuilder.newBuilder()
.maximumSize(2)
.expireAfterWrite(24, TimeUnit.HOURS)
.build(
new CacheLoader[Int, String] {
def load(path: Int): String = {
path + "hello"
}
}
)
看起来没问题,但是创建的对象的推断类型是LoadingCache[Int with AnyRef, String]:
val cache: LoadingCache[Int with AnyRef, String] = CacheBuilder.newBuilder()
.maximumSize(2)
.expireAfterWrite(24, TimeUnit.HOURS)
.build(
new CacheLoader[Int, String] {
def load(path: Int): String = {
path + "hello"
}
}
)
当我尝试获取像本例这样的元素时,会发生错误:
cache.get(1)
Scala 编译器错误:
[ERROR] error: type mismatch;
[INFO] found : Int(1)
[INFO] required: Int
[INFO] cache.get(1)
[INFO] ^
有人可以指出为什么会出现这样的错误以及我做错了什么吗?
环境:
- 谷歌 Guava 15.0
- 斯卡拉2.11.5
最佳答案
On 1
不是带有 AnyRef 的 Int
你问题中的编译错误与Guava没有任何关系。此处的代码片段会产生相同的错误:
val h = new scala.collection.mutable.HashMap[Int with AnyRef, String]
h(3) = "hello"
println("Get 3: " + h.get(3))
给出
error: type mismatch;
found : Int(3)
required: Int
这是由 Int 与 AnyRef
引起的:由于 Int
是 AnyVal
的子类型,因此 Int 与 AnyRef 的交集
code> 为空,根本不存在该类型的任何实例。
现在来看看问题的根本原因。
问题是,当你调用 .build()
时,scala 编译器找不到可以作为 .build[Int, String]
工作的版本,因为有没有未装箱整数的版本。因此,编译器会推断 .build[AnyRef with Int, String]
,并构建一个不可用的缓存结构。
要避免这种情况,请使用 java.lang.Integer
而不是 Int
。这里使用 guava 15.0 scala 2.11 编译并运行:
import com.google.common.cache._
import java.util.concurrent._
val cache: LoadingCache[java.lang.Integer, String] = CacheBuilder.newBuilder()
.maximumSize(2)
.expireAfterWrite(24, TimeUnit.HOURS)
.build[java.lang.Integer, String](
new CacheLoader[java.lang.Integer, String] {
def load(path: java.lang.Integer): String = {
path + "hello"
}
}
)
cache.put(42, "hello, world")
println(cache.get(42))
它应该与 scala 的 Int
无缝协作,因为 scala 无论如何都会将 Int
自动装箱到 java.lang.Integer
中。
类似错误的解答:
关于scala - 从 scala 代码中使用 Google guava 时出现编译器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48892516/