简体   繁体   English

从Scala代码使用Google番石榴时出现编译器错误

[英]compiler error when using Google guava from scala code

I m using Google Guava from a scala code. 我正在使用Scala代码中的Google Guava。 And an issue occurs when I m trying to use Int as a key type like in the example: 当我尝试使用Int作为示例中的键类型时,会发生问题:

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] : 看起来不错,但是所创建对象的推断类型是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: Scala编译器错误:

[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: ENV:

  • Google Guava 15.0 谷歌番石榴15.0
  • Scala 2.11.5 斯卡拉2.11.5

On 1 not being an Int with AnyRef 1不是Int with AnyRefInt 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. 这是由Int with AnyRefInt with AnyRef引起的:由于IntAnyVal子类型, AnyVal Int with AnyRef的交集为空,因此根本不存在具有该类型的任何实例。


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. 问题在于,当您调用.build() ,scala编译器无法找到将用作.build[Int, String]版本,因为没有针对未装箱整数的版本。 So instead, the compiler infers .build[AnyRef with Int, String] , and builds an unusable cache structure. 因此,编译器改为推断.build[AnyRef with Int, String] ,并构建一个不可用的缓存结构。

To avoid this, use java.lang.Integer instead of Int . 为了避免这种情况,请使用java.lang.Integer而不是Int This here compiles and runs with guava 15.0 scala 2.11: 这是在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 Int s into java.lang.Integer anyway. 它应该与scala的Int无缝配合,因为无论如何scala会将Int装箱到java.lang.Integer


Answers for similar errors: 类似错误的答案:

  1. Scala Guava type mismatch issue Scala Guava类型不匹配问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM