从Scala代码使用Google番石榴时出现编译器错误 [英] compiler error when using Google guava from scala code

查看:92
本文介绍了从Scala代码使用Google番石榴时出现编译器错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Scala代码中的Google Guava。当我尝试将Int用作示例中的键类型时,就会出现问题:

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"
        }
      }
    )

这似乎很好,但是所创建对象的推断类型为 LoadingCache [Int with AnyRef,String]

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编译器错误:

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

推荐答案

1 上不是 Int with AnyRef


问题中的编译错误与番石榴无关。此代码段在此处产生相同的错误:

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))

给予

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

这是由<$ c引起的$ c> Int with AnyRef :因为 Int AnyVal 的子类型,所以交集 Int with AnyRef 为空,根本就不存在该类型的实例。

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.

问题是,当您调用 .build()时,scala编译器无法找到将用作 .build [Int,String] ,因为没有拆箱整数的版本。因此,相反,编译器推断 .build [带有Int,String的AnyRef] ,并构建了无法使用的缓存结构。

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.

为避免这种情况,请使用 java.lang.Integer 代替 Int 。这是在guava 15.0 scala 2.11上编译并运行的:

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))

它应该与Scala的 Int无缝运行,因为scala会将 Int s自动装箱到 java.lang.Integer 中。

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

类似错误的答案:


  1. Scala Guava类型不匹配问题

  1. Scala Guava type mismatch issue

这篇关于从Scala代码使用Google番石榴时出现编译器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆