Почему использование foreach, map, flatMap и т.д. считается лучше, чем использование get для Scala Options? Если я использую isEmpty, я могу безопасно позвонить get.
Почему foreach лучше, чем получить для Scala Options?
Ответ 1
Ну, это вроде как возвращается, чтобы "рассказать, не спрашивать". Рассмотрим эти две строки:
if (opt.isDefined) println(opt.get)
// versus
opt foreach println
В первом случае вы смотрите внутри opt, а затем реагируете в зависимости от того, что видите. Во втором случае вы просто говорите opt, что вы хотите сделать, и пусть это будет иметь дело с ним.
В первом случае слишком много сказано о Option, реплицирует внутреннюю логику, хрупко и подвержено ошибкам (это может привести к ошибкам во время выполнения, а не ошибкам во время компиляции, если они написаны неправильно).
Добавьте к этому, он не является составным. Если у вас есть три варианта, один для понимания заботится о них:
for {
op1 <- opt1
op2 <- opt2
op3 <- opt3
} println(op1+op2+op3)
С if все начинает быстро запутываться.
Ответ 2
Одна из приятных причин использовать foreach - это разбор чего-либо с вложенными параметрами. Если у вас есть что-то вроде
val nestedOption = Some(Some(Some(1)))
for(opt1 <- nestedOption;
opt2 <- opt1;
opt3 <- opt2) println(opt3)
Консоль печатает 1. Если вы распространите это на случай, когда у вас есть класс, который опционально содержит ссылку на что-то, что, в свою очередь, хранит другую ссылку, то для понимания вы можете избежать гигантской "пирамиды" проверки None/Some.
Ответ 3
Есть уже отличные ответы на фактический вопрос, но для более Option -foo вам обязательно нужно проверить Титановый лист возможностей Тони Морриса.
Ответ 4
Причина, по которой более удобно применять такие вещи, как map, foreach и flatMap, непосредственно к Option вместо использования get, а затем выполнение функции состоит в том, что она работает либо на Some или None, и вам не нужно делать специальные проверки, чтобы убедиться, что это значение.
val x: Option[Int] = foo()
val y = x.map(_+1) // works fine for None
val z = x.get + 1 // doesn't work if x is None
Результат для y здесь - Option[Int], что желательно, так как если x является необязательным, то y также может быть неопределенным. Поскольку get не работает на None, вам придется выполнить кучу дополнительной работы, чтобы убедиться, что вы не получили никаких ошибок; дополнительная работа, выполненная для вас map.
Ответ 5
Проще говоря:
-
Если вам нужно что-то сделать (процедура, когда вам не нужно фиксировать возвращаемое значение каждого вызова), только если опция определена (т.е. есть
Some): используйтеforeach( если вы заботитесь о результатах каждого вызова, используйтеmap) -
Если вам нужно что-то сделать, если определенная опция и что-то еще, если это не так: используйте
isDefinedв выражении if -
Если вам нужно значение, если параметр является
Some, или значением по умолчанию, если оноNone: используйтеgetOrElse
Ответ 6
Попытка выполнить наши операции с get более насущным стилем, где вам нужно делать то, что нужно делать и как делать. Другими словами, мы диктуем вещи и копаем больше в внутренности Options. Где map,flatmap - более функциональный способ делать вещи, где мы говорим, что делать, а не как делать.