Scala: Грешка при несъответствие на типа при използване на ArrayList

Може ли някой да обясни защо възниква следната грешка (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]()

има и много подобна грешка.


person Dave L.    schedule 10.02.2014    source източник


Отговори (2)


Опитайте тази:

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

Както можете да видите, компилира се добре. Проблемът беше, че 0 има тип Int, а не Integer. Така че трябва да кажете на scala по някакъв начин, че искате да конвертирате 0 в Integer стойност.

В настоящия си вид вашият код задейства компилатора да търси метод binarySearch, който приема и ArrayList[Integer] като първи параметър и Int като втори параметър.

person Régis Jean-Gilles    schedule 10.02.2014
comment
Има смисъл, но все още не съм сигурен, че разбирам логиката на съобщението. Дали Integer не отговаря на _ <: Comparable[_ >: Any], но Int отговаря? - person Dave L.; 10.02.2014
comment
Е, компилаторът не знае дали грешката идва от типа на първия параметър, или от типа на втория (или и двата). Всичко, което може да каже е, че тази комбинация от типове е невалидна (няма метод binarySearch, който може да вземе ArrayList[Integer] като първи апраметър и Int като втори. Разбира се, може да е по-добре, ако компилаторът просто каже, че не може да направи извикване предвид типовете вход, вместо да излъчва съобщение, което може да ви накара да мислите, че само първият параметър е дефектен. - person Régis Jean-Gilles; 10.02.2014
comment
Но ако направя абсолютно същите стъпки, просто променяйки първоначалното List създаване на new java.util.ArrayList[Int](), получавам същата грешка! Това не би ли трябвало да работи според твоето обяснение? Благодаря. - person Dave L.; 10.02.2014
comment
java.util.ArrayList[Int] не съответства на java.util.List[_ <: java.lang.Comparable[_ >: Any]] просто защото Int не е подтип на java.lang.Comparable (но java.lang.Integer е). Така че компилаторът е напълно прав да се оплаква, ако подадете екземпляр от java.util.ArrayList[Int] към binarySearch - person Régis Jean-Gilles; 10.02.2014

Дефиницията на 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. Тъй като първият е от тип List<Integer>, а по-късният е от тип int според Java. Така че това се преобразува в Scala съответно в Integer и int, както е обяснено по-долу:

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

scala> classOf[Int]
res10: Class[Int] = int
person tuxdna    schedule 10.02.2014
comment
@david: Да, сега има много смисъл :-) - person tuxdna; 10.02.2014