Ошибка несоответствия типа Scala 2.7.x при передаче null для ссылочного типа

Следующий код Scala не может быть скомпилирован в Scala 2.7.7, обнаружена ошибка несоответствия типа ": Null (null) required: T" в последней строке:

/**
 * @param [T] key type
 */
class Key[T] 

class Entry[T](val k: Key[T], val v: T)

def makeEntry[T <: AnyRef] = new Entry[T](new Key[T], null)

Я полностью осведомлен о вреде нулей, но достаточно сказать, что мне действительно нужно это сделать. Это ошибка компилятора или ошибка программиста?

Изменить. Чтобы уточнить, T - это параметр типа, а не конкретный тип. Я не осознавал, что исходный вопрос был двусмысленным, пока не прочитал ответ Карла более внимательно.


person Aaron Novstrup    schedule 10.12.2009    source источник


Ответы (4)


По-видимому, правильный способ сделать это в 2.7 - :

class Key[T]

class Entry[T](val k: Key[T], val v: T)

def makeEntry[T >: Null] = new Entry(new Key[T], null)
person Aaron Novstrup    schedule 11.12.2009

Вот определение, которое охватывает null:

Тип Null - это подтип всех ссылочных типов; его единственный экземпляр - пустая ссылка. Поскольку Null не является подтипом типов значений, null не является членом любого такого типа. Например, невозможно присвоить значение null переменной типа Int.

На английском языке это означает, что вы не можете назначить null типу значения, но допустимо назначать любому ссылочному типу.

У меня возникли проблемы с определением, является ли T значением или ссылочным типом; но это ответит на ваш вопрос.

Поскольку вы определяете T как подтип AnyRef, я предполагаю, что это ссылка, и объяснение "ошибки" кажется более вероятным; тем более, что Митч Блевинс только что сказал, что код работает под 2.8.

person Carl Smotricz    schedule 10.12.2009
comment
Похоже, все пришли к единому мнению, что это должно сработать, поэтому я собираюсь принять ваш ответ, если не появятся свидетельства обратного. - person Aaron Novstrup; 11.12.2009

Попробуй это:

class Key[T <: AnyRef]

class Entry[T <: AnyRef](val k: Key[T], val v: T)

def makeEntry[T <: AnyRef] = new Entry[T](new Key[T], null.asInstanceOf[T])

Я не уверен, почему требуется "asInstanceOf [T]", но похоже, что это так.

person Erik Engbrecht    schedule 10.12.2009
comment
Не работал в Scala (и я вообще-то не могу использовать эту технику, потому что Key и Entry на самом деле являются Java-классами, определенными в другой библиотеке) - person Aaron Novstrup; 11.12.2009

Вы пробовали это?

def makeEntry[T <: AnyRef] = new Entry[T](new Key[T], null: T)
person Mitch Blevins    schedule 10.12.2009
comment
Та же проблема с использованием REPL и scala 2.7.5. - person paradigmatic; 11.12.2009
comment
Я не понимал, что это правильный синтаксис. :) Попробовал, тоже не работает. - person Aaron Novstrup; 11.12.2009
comment
У меня нет под рукой 2.7 для тестирования, но я бы также попробовал null.asInstanceOf [T] - person Mitch Blevins; 11.12.2009