В Scala я постепенно утратил привычку думать на языке Java / C, ориентируясь на поток управления, и привык идти вперед и сначала получать интересующий меня объект, а затем обычно примените что-то вроде match
или map ()
или foreach ()
для коллекций. Мне это очень нравится, так как теперь он кажется более естественным и точным способом структурирования моего кода.
Мало-помалу мне хотелось, чтобы я мог так же программировать условия; то есть сначала получить логическое значение, а затем сопоставить
с ним для выполнения различных действий. Однако полное соответствие
кажется излишним для этой задачи.
Сравните:
obj.isSomethingValid match {
case true => doX
case false => doY
}
vs. что бы я написал со стилем, более близким к Java:
if (obj.isSomethingValid)
doX
else
doY
Затем я вспомнил сообщения Smalltalk ifTrue:
и ifFalse:
(и их варианты). Можно ли написать что-то подобное в Scala?
obj.isSomethingValid ifTrue doX else doY
с вариантами:
val v = obj.isSomethingValid ifTrue someVal else someOtherVal
// with side effects
obj.isSomethingValid ifFalse {
numInvalid += 1
println("not valid")
}
Кроме того, можно ли сделать этот стиль доступным для простых типов с двумя состояниями, таких как Option
? Я знаю, что более идиоматический способ использования Option
- рассматривать его как коллекцию и вызывать filter ()
, map ()
, exists ()
, но часто, в конце я обнаружил, что хочу выполнить некоторые doX
, если они определены, и некоторые doY
, если это не так. Что-то вроде:
val ok = resultOpt ifSome { result =>
println("Obtained: " + result)
updateUIWith(result) // returns Boolean
} else {
numInvalid += 1
println("missing end result")
false
}
Для меня это (все еще?) Выглядит лучше, чем полномасштабное совпадение
.
Я предлагаю базовую реализацию, которую придумал; приветствуются общие комментарии к этому стилю / технике и / или лучшему воплощению!