Выдает ли компилятор Scala 2.9.1 информацию о параметрах типа? - PullRequest
4 голосов
/ 10 октября 2011

Я пишу некоторый код Java, который зависит от кода Scala (который я также написал). Попытка предоставить аргумент с параметризованным типом, похоже, работает, если Scala скомпилирован с 2.8.0, но не удается, если я использую 2.9.1.

(упрощенный) код Scala выглядит примерно так:

package test

import collection.JavaConversions._

class SomeClass {
  def foo(numbers: java.util.Set[Long]) {
    numbers.foreach(println(_))
  }
}

Это успешно компилируется с обоими компиляторами 2.8.0 и 2.9.1. Код Java выглядит примерно так:

package test;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class App {

    public static void main(String[] args) {
        new SomeClass().foo(new HashSet<Long>(Arrays.asList(1L, 2L, 3L)));
    }

}

Если я скомпилирую Scala с помощью компилятора 2.8.0, то Java скомпилируется счастливо (с помощью компилятора Java 1.6.0_26). Однако если я скомпилирую Scala с 2.9.1, то компилятор Java завершится с ошибкой:

test\App.java:16: foo(java.util.Set<java.lang.Object>) in test.SomeClass cannot be applied to (java.util.HashSet<java.lang.Long>)
            sc.foo(new HashSet<Long>(Arrays.asList(1L, 2L, 3L)));
              ^
1 error

Так что, похоже, что Scala 2.8.0 сохраняет в байт-коде информацию о том, что numbers имеет тип Set<Long>, компилятор 2.9.1 генерирует байт-код, где numbers - это Set<Object>.

Это ошибка? Является ли это неблагоприятным (для меня) побочным эффектом преднамеренного изменения? (Scala changelog упоминает "различные исправления в ... JavaConversions для более плавного взаимодействия"). Если да, могу ли я что-нибудь сделать, чтобы заставить это работать с 2.9.1?

Ответы [ 2 ]

2 голосов
/ 11 октября 2011

Короткий ответ, это сложно.Any в системе типов Scala является отличным объединителем, но к тому времени, когда вы находитесь на Java-земле, выдает полную фикцию.

Упрощенное представление, сделанное до версии 2.9, было непродуманным и сломало вещи.

Чтобы понять причину проблемы, прочитайте отчеты Пола Филлипса из списков рассылки:

http://www.scala -lang.org / node / 9157

http://www.scala -lang.org / node / 8888

http://www.scala -lang.org / node /8980

2 голосов
/ 10 октября 2011

Хорошо, поскольку мой снимок в темноте в комментарии оказался удачным, так же, как и ответ.

Он работает с

def foo(numbers: java.util.Set[java.lang.Long])

java.lang.Long - не то же самое, что Long Скала.Примечательно, что Set[java.lang.Long] может содержать null, а Set[Long] не должен (если только система типов не была обойдена каким-либо неконтролируемым приведением).Это несмотря на то, что Set реализован как содержащий ссылки в обоих случаях;во втором случае они гарантированно не равны нулю.

Идентификация Set[Long] и Set[java.lang.Long] открывает лазейку в системе типов.При этом, я не знаю, было ли изменение предназначено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...