【问题标题】:Scala: Erroneous type mismatch error using ArrayListScala:使用 ArrayList 的错误类型不匹配错误
【发布时间】:2014-02-10 15:48:12
【问题描述】:

谁能解释为什么会出现以下错误(Scala 2.10.3)?

scala> new java.util.ArrayList[Integer]()
res0: java.util.ArrayList[Integer] = []

scala> res0.add(0)
res1: Boolean = true

scala> java.util.Collections.binarySearch(res0, 0)
<console>:9: error: type mismatch;
 found   : java.util.ArrayList[Integer]
 required: java.util.List[_ <: Comparable[_ >: Any]]
              java.util.Collections.binarySearch(res0, 0)
                                                 ^

以下确实有效:

scala> java.util.Collections.binarySearch[Integer](res0, 0)
res4: Int = 0

编译器会抱怨一个特定的类型,直到我更明确了解那个不正确的类型,然后它才会接受它,这似乎很奇怪。

编辑:

还请注意如果您将第一步更改为:

scala> new java.util.ArrayList[Int]()

还有一个非常相似的错误。

【问题讨论】:

    标签: java scala type-inference scala-collections


    【解决方案1】:

    试试这个:

    java.util.Collections.binarySearch(res0, 0: Integer)
    

    如您所见,它编译得很好。 问题是0 的类型为Int,而不是Integer。所以你必须以某种方式告诉 scala 你想将 0 转换为 Integer 值。

    就目前而言,您的代码会触发编译器查找方法 binarySearch,该方法将 ArrayList[Integer] 作为其第一个参数,并将 Int 作为其第二个参数。

    【讨论】:

    • 有道理,但我仍然不确定我是否理解消息的逻辑。是不是Integer不符合_ &lt;: Comparable[_ &gt;: Any],而Int符合?
    • 那么编译器不知道错误是来自第一个参数的类型,还是来自第二个参数的类型(或两者兼而有之)。它所能告诉的只是这种类型组合是无效的(没有方法binarySearch可以将ArrayList[Integer]作为其第一个参数,将Int作为第二个参数。当然,如果编译器可能会更好只是说它不能根据输入类型进行调用,而不是发出一条消息,让你认为只有第一个参数有问题。
    • 但是如果我执行完全相同的步骤,只需将初始的 List 创建更改为 new java.util.ArrayList[Int](),我就会得到同样的错误!你的解释不应该有效吗?谢谢。
    • java.util.ArrayList[Int] 不符合 java.util.List[_ &lt;: java.lang.Comparable[_ &gt;: Any]] 仅仅是因为 Int 不是 java.lang.Comparable 的子类型(但 java.lang.Integer 是)。因此,如果您将java.util.ArrayList[Int] 的实例传递给binarySearch,编译器完全可以抱怨
    【解决方案2】:

    binarySearch的定义如下:

    使用二分搜索算法在指定列表中搜索指定对象。

    static <T> int
    binarySearch(List<? extends Comparable<? super T>> list, T key)
    

    如您所见,list 和 key 在类型 T 上参数化。现在 Scala 编译器尝试在以下调用中推断 list 的类型:

    scala> java.util.Collections.binarySearch(l, 0)
    <console>:9: error: type mismatch;
     found   : java.util.ArrayList[Integer]
     required: java.util.List[_ <: Comparable[_ >: Any]]
                  java.util.Collections.binarySearch(l, 0)
    

    并且参数list和key之间的共同类型是Any。因为根据 Java,前者是 List&lt;Integer&gt; 类型,而后者是 int 类型。因此,这在 Scala 中分别转换为 Integer 和 int,如下所述:

    scala> classOf[Integer]
    res9: Class[Integer] = class java.lang.Integer
    
    scala> classOf[Int]
    res10: Class[Int] = int
    

    【讨论】:

    • @david:是的,现在很有意义 :-)
    猜你喜欢
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2022-11-01
    • 1970-01-01
    相关资源
    最近更新 更多