2013-07-13 2 views
1

я начал с этим (в методе Play Action):Более функциональный и лаконичный способ написать это в Scala

val foo = JPA.em.find(classOf[Foo], id) 
    if (foo == null) NotFound("Bad Id") else Ok(Json.toJson(foo)) 

не нравится его императивность, я пошел на это:

Option(JPA.em.find(classOf[Foo], id)) match { 
     case Some(foo) => Ok(Json.toJson(foo)) 
     case None => NotFound("Bad Id") 
    } 

более функциональный, но дольше.

Приносим извинения за общий характер вопроса, но я уверен, что ответы могут быть полезны для многих.

+0

Я не уверен, что «более функциональный» и «лаконичный», поскольку критерии сложны и достаточно быстры для решения вопроса SO. * Может быть * [codereview.se], но я не знаком с политиками этого сайта и не имеет ли «у меня этот код, сделайте это лучше», для него достаточно конкретных вопросов. – millimoose

+1

Тем не менее, ваш последний пример больше похож на то, что вы говорите по поводу соглашений FP, а не на самом деле функционально каким-либо значимым образом. Я придерживаюсь первого и беспокоюсь о том, где важны преимущества FP (например, возможность компоновки фактических функций), а не одержимость над отдельными утверждениями. Это похоже на попытку сделать код «более объективным», заменив методы интерфейсом «ICallable». – millimoose

+0

Дело не в том, чтобы сделать этот фрагмент кода лучше, а просто понять, как это можно сделать в целом. –

ответ

4
Option(JPA.em.find(classOf[Foo], id)).map(foo=>Ok(Json.toJson(foo))).getOrElse(NotFound("Bad Id")) 
+2

Начиная с версии 2.10 также существует опция «Option.fold», которая как «map», так и 'getOrElse' одним способом. – sschaef

+0

А я этого не знал. – monkjack

1

Это определенно стоит оборачивать небезопасное API, Java, как это с некоторыми многоразовыми методами, которые возвращают Option с, например

def findOpt[T](cls: Class[T], id: Object): Option[T] = 
    Option(JPA.em.find(cls, id)) 

потребляя этот API, вместо того, чтобы с помощью JPA непосредственно, означает, что вы не делаете вам нужно беспокоиться о нулевых проверках в другом месте вашего кода. Все это рассматривается в одном месте.

Теперь вы можете решить, следует ли использовать match, или fold, или map/getOrElse; важно, чтобы возможное отсутствие результата было представлено в типе findOpt.

findOpt(classOf[Foo], id) map (foo => OK(Json.toJson(foo)) getOrElse NotFound("Bad Id") 
+0

ЕСЛИ цель состоит в том, чтобы пропагандировать результат и обрабатывать его несколько раз в коде, тогда ДА стоит обернуть в 'Option'. Если это простая одноразовая проверка, как было предложено по этому вопросу, то я согласен с ответом (ниже/выше). –

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