compiler error when using Google guava from scala code

前端 未结 1 1721
青春惊慌失措
青春惊慌失措 2021-01-22 01:31

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()
    .maxim         


        
1条回答
  •  清歌不尽
    2021-01-22 02:11

    On 1 not being an Int with AnyRef

    The compile error in your question doesn't have anything to do with Guava. This snippet here produces the same error:

    val h = new scala.collection.mutable.HashMap[Int with AnyRef, String]
    h(3) = "hello"
    println("Get 3: " + h.get(3))
    

    gives

    error: type mismatch;
    found   : Int(3)
    required: Int
    

    This is caused by the Int with AnyRef: since Int is subtype of AnyVal, the intersection Int with AnyRef is 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.Integer instead of Int. This here compiles and runs with 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))
    

    It should work seamlessly with scala's Int, because scala autoboxes Ints into java.lang.Integer anyway.


    Answers for similar errors:

    1. Scala Guava type mismatch issue

    0 讨论(0)
提交回复
热议问题