I m using Google Guava from a scala code. And an issue occurs when I m trying to use Int as a key type like in the example:
CacheBuilder.newBuilder()
.maximumSize(2)
.expireAfterWrite(24, TimeUnit.HOURS)
.build(
new CacheLoader[Int, String] {
def load(path: Int): String = {
path + "hello"
}
}
)
It seems to be fine, but the inferred type of created object is 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"
}
}
)
And the error occurs when I m trying to get an element like in this example:
cache.get(1)
Scala compiler error:
[ERROR] error: type mismatch;
[INFO] found : Int(1)
[INFO] required: Int
[INFO] cache.get(1)
[INFO] ^
Can someone point me out why such error appears and what I m doing wrong?
ENV:
- Google Guava 15.0
- Scala 2.11.5
On
1not being anInt with AnyRefThe compile error in your question doesn't have anything to do with Guava. This snippet here produces the same error:
gives
This is caused by the
Int with AnyRef: sinceIntis subtype ofAnyVal, the intersectionInt with AnyRefis empty, there simply cannot exist any instances with that type.Now to the root cause of the problem.
The problem is that when you call
.build(), the scala compiler cannot find a version that would work as.build[Int, String], because there is no version for unboxed integers. So instead, the compiler infers.build[AnyRef with Int, String], and builds an unusable cache structure.To avoid this, use
java.lang.Integerinstead ofInt. This here compiles and runs with guava 15.0 scala 2.11:It should work seamlessly with scala's
Int, because scala autoboxesInts intojava.lang.Integeranyway.Answers for similar errors: