1

这纯粹是一个编码风格的问题。

我正在调用的函数返回一个Option,如果它等于 ,我想采取特定的操作None

例如,假设我正在尝试在启动时创建一个默认用户(如果它尚不存在)。我会调用一个函数来尝试查找与默认用户匹配的用户,并返回一个Option[User].

如果该返回值为None,我想运行一些用户创建代码。如果没有,我就完了。

我想知道最惯用的 Scala 语法是什么。到目前为止,我所拥有的是:

def getUser(name: String): Option[User] = ...

getUser("admin") getOrElse createUser("admin", "ChangeThisNow!")

getUser("admin") match {
    case None => createUser("admin", "ChangeThisNow!")
    case _    =>
}

if(getUser("admin") == None) createUser("admin", "ChangeThisNow!")

第一个解决方案似乎是最实用的解决方案,但我不禁觉得可能会有更好的解决方案 - 可能通过使用部分应用的功能,我承认我仍然有点模糊。

4

3 回答 3

4

由于在您的情况下,目标是引起副作用,因此我会使用条件来强调这一点,而不是使用getOrElse.

if (getUser("admin").isEmpty) 
  createUser("admin", "ChangeThisNow!")
于 2013-08-02T12:26:47.437 回答
1

请记住,scala 是一种多范式语言。除了语法之外,您还需要考虑内聚力(单一职责)等概念,因此除了在语法中使用的实际惯用语之外,您还可以考虑对象的组成。

OO 方法可能是装饰 getUser 所属的对象/类,以将创建用户的问题放在包装器中,以便调用 getUser 函数的其他代码永远不必处理该问题。这非常符合开放/封闭原则和单一职责。这有点像一个贫乏的领域模型反模式,但可以展示如何使用 OO 将对话扩展到实际设计中。

模式匹配或 getOrElse 都是合理的解决方案。一般来说,如果语句不用于像选项这样的 Monads - 至少不是我看到的那样。

无论哪种方式,我相信即使有副作用(用户创建),表达式也应该返回结果。

case class User(name: String)    

class UserService {
  def getUser(name: String): Option[User] = ???
  def createUser(name: String): User = ???
}

class UserServiceDecorator extends UserService {
  override def getUser(name: String): Option[User] =  
    Some(super.getUser(name).getOrElse(super.createUser(name)))
}
于 2013-08-02T19:50:36.937 回答
0

真正做到这一点的最好方法是将结果分配给一个有意义的变量名,这样你未来的代码就不需要知道是否createUser被调用了。

val user = getUser("admin").getOrElse(createUser("admin", "ChangeThisNow!"))

这样,user无论您是否创建了新用户,您都可以使用该变量。

于 2013-08-02T13:36:29.680 回答