2013-08-24 3 views
0

Ниже приведены действительные заявления в Scala:Почему я могу присвоить значение null опции?

scala> var x: Option[Int] = Some(3) 
x: Option[Int] = Some(3) 

scala> var x: Option[Int] = None 
x: Option[Int] = None 

Следующая недействителен:

scala> var x: Option[Int] = 3 
<console>:7: error: type mismatch; 
found : Int(3) 
required: Option[Int] 
     var x: Option[Int] = 3 

До сих пор эти примеры имеют смысл для меня; значение типа Option [T] может быть любого типа Some [T] или None, поэтому компилятор не позволяет присваивать значение, которое не имеет ни одного типа.

Однако компилятор Scala появляется принять это:

scala> val x: Option[Int] = null 
x: Option[Int] = null 

если я попробую сделать по шаблону на опции (например, как показано ниже), я получить неудачи я не ожидал - почему компилятор не защищает меня от этого, отвергая присвоение null?

x match { 
    case Some(y) => println("Number: ", y) 
    case None => println("No number") 
} 
+3

Любая ссылка может быть нулевой; это просто неудачное следствие работы на JVM. –

+0

Спасибо Кристофер! Я просто прочитал [эту статью] (http://www.naildrivin5.com/blog/2010/07/30/in-offense-of-scala-option.html), в которой говорится: «Конечно, ничто из этого не спасает вас от null, потому что Scala с удовольствием присваивает нулевое значение никому. Это похоже на то, что все это кажется немного бессмысленным ». Это немного разочаровывает; Я исходил из предположения, что шаблон соответствия Option (Some/None) был завершен, но на самом деле, чтобы быть полным, я предполагаю, что вам нужно будет сопоставить Some/None/null и провести дополнительную проверку значения, которое вы получаете от Some. –

+3

При дальнейшем чтении, я думаю, я понимаю немного лучше. Опция больше связана с передачей _intent_ программиста, что определенный метод может вернуть значение или нет. Если вызываемый код хорошо себя ведет, вызывающему абоненту не нужно явно обращаться к null, потому что вызывающий его не ожидает. Как упоминалось [здесь] (http://james-iry.blogspot.jp/2010/08/why-scalas-and-haskells-types-will-save.html), «опыт, который все разработчики Scala, которых я знаю, заключается в том, что NPE в основном является проблемой только при работе с существующими библиотеками Java, потому что программисты и библиотеки Scala избегают этого ». –

ответ

6

Если вы посмотрите на Scala class hierarchy, вы увидите, что все классы, вытекающие из AnyRef супер классы Null, и любой такой супер класс может быть присвоено значение null. Поскольку Option является одним из таких классов, вы можете назначить ему Null.

Обратите внимание, что оба Some и None.type (то есть, тип синглтон из None объекта) являются супер классы Null, так null является допустимым значением для любого из них.

Вы не можете назначить 3 для Option, поскольку 3 не является значением подпроцесса класса Option (очевидно).

0

Ответ на вопрос, который вы, вероятно, намеревались спросить идет что-то вроде этого:

Идиоматической Scala никогда не будет использовать null. Нулевые ссылки существуют исключительно для взаимодействия с Java и другими языками JVM. Если вы видите null в коде Scala, он должен немедленно привлечь внимание. Вы бы никогда не использовали null по ошибке, поэтому предупреждение о компиляторе не нужно. Как отмечалось в ответе Даниэля Собраля и комментариях, компилятор не может обеспечить защиту от null.

Смежные вопросы