假设我有一个函数getCustomers和getOrdersByCustomer.
def getCustomer():List[Customer] = ... def getOrdersByCustomer(cust: Customer): List[Order] = ...
现在我可以轻松定义一个函数getOrdersOfAllCustomers
def getOrdersOfAllCustomers(): List[Order] = for(cust <- getCustomer(); order <- getOrderByCustomer(cust)) yield order
到目前为止,这么好但是如果getCustomer和getOrdersByCustomer返回列表的选项呢?
def getCustomer():Option[List[Customer]] = ... def getOrdersByCustomer(cust: Customer): Option[List[Order]] = ...
现在我想实现两种不同的getOrdersOfAllCustomers():
>如果其中一个函数返回None,则返回None;
>如果getCustomer返回None,则返回None,并且不关心getOrdersByCustomer是否返回None.
你会如何建议实施它?
解决方法
我认为你应该考虑三种可能性 – 一个填充列表,一个空列表或一个错误 – 并避免许多不优雅的测试,以找出发生了哪一个.
所以使用Try with List:
def getOrdersOfAllCustomers(): Try[List[Order]] = { Try(funtionReturningListOfOrders()) }
如果一切顺利,您将获得成功[List [Order]];如果没有,失败[列表[订单]].
这种方法的优点在于无论发生了什么 – 填充列表,空列表或错误 – 您可以使用列表完成所需的所有操作.这是因为Try就像Option一样是monad.继续过滤,将每个,地图等过滤到心脏的内容,而不关心这三者中的哪一个发生.
一件事是,当你必须弄清楚成功或失败是否发生时,这个尴尬的时刻.然后使用匹配表达式:
getOrdersOfAllCustomers() match { case Success(orders) => println(s"Awww...yeah!") case Failure(ex) => println(s"Stupid Scala") }
即使您不使用Try,我也恳请您不要处理与填充列表不同的空列表.