Я думаю, что ключ кроется в ответе Synesso: опция не в первую очередь полезна как громоздкий псевдоним для нуля, но как полноценный объект, который может помочь вам с логикой. *
Проблема с нулем в том, что это отсутствие объекта. У него нет методов, которые могли бы помочь вам справиться с этим (хотя, как разработчик языка, вы можете добавлять к своему языку все более длинные списки функций, которые эмулируют объект, если вы действительно этого хотите).
Одна вещь, которую Option может сделать, как вы продемонстрировали, это эмулировать null; Затем вы должны проверить необычное значение «None» вместо необычного значения «NULL». Если вы забудете, в любом случае произойдут плохие вещи. Опция делает его менее вероятным случайным образом, так как вы должны набрать «get» (что должно напомнить вам, что может быть null, я имею в виду None), но это небольшое преимущество в обмен на дополнительный объект-обертку.
Там, где Option действительно начинает показывать, что его сила помогает вам разобраться с концепцией «я хотел чего-то, но я не хочу на самом деле иметь».
Давайте рассмотрим некоторые вещи, которые вы, возможно, захотите сделать с вещами, которые могут быть нулевыми.
Может быть, вы хотите установить значение по умолчанию, если у вас есть ноль. Давайте сравним Java и Scala:
String s = (input==null) ? "(undefined)" : input;
val s = input getOrElse "(undefined)"
Вместо несколько громоздкой конструкции?: У нас есть метод, который имеет дело с идеей «использовать значение по умолчанию, если я нулевой». Это немного очищает ваш код.
Возможно, вы захотите создать новый объект, только если у вас есть реальная стоимость. Сравните:
File f = (filename==null) ? null : new File(filename);
val f = filename map (new File(_))
Scala немного короче и снова избегает источников ошибок. Затем рассмотрите кумулятивную выгоду, когда вам нужно объединить все вместе, как показано в примерах Синессо, Даниэля и парадигматика.
Это не значительное улучшение, но если вы все сложите, оно того стоит везде, за исключением очень высокопроизводительного кода (где вы хотите избежать даже крошечных накладных расходов на создание Some ( х) объект-обертка).
Использование совпадений на самом деле не так уж полезно, кроме как в качестве устройства, предупреждающего вас о нулевом / нулевом случае. Когда это действительно полезно, это когда вы начинаете цепочку, например, если у вас есть список опций:
val a = List(Some("Hi"),None,Some("Bye"));
a match {
case List(Some(x),_*) => println("We started with " + x)
case _ => println("Nothing to start with.")
}
Теперь вы можете сложить все случаи None и List-is-empty вместе в одно удобное утверждение, которое извлекает именно то значение, которое вы хотите.