3

我做了一个从数据库中获取用户的定义。

 def user(userId: Int) : User = database withSession {
    (for{
      u <- Users if u.id === userId} 
    yield u).first
  }

如果与不存在的 userId 一起使用,数据库可能会返回一个空列表。
但是我看不到何时会提供不存在的 userId。例如,我的 userId 是从登录用户中获取的。如果提供了不存在的 userId,那么我认为可以使请求失败。

有什么想法吗?

4

3 回答 3

4

不,很难使请求失败:

def user(userId: Int) : Option[User] // is OK
def user(userId: Int) : Either[String,User] // is OK
def user(usedId: Int) : User // is not OK

或者你可以创建一个类型(一个概念)来封装一个 Integer 以确保它是一个有效的 UserId (在出生时)。

sealed case class UserId(u:Int) //extends AnyVal // If it's scala 2.10.0

object UserId {
    def get(i:Int) : Option[UserId] = //some validation

} /// ....

def  user(userId:UserId) : User //is OK // well it depends on the semantic of user destruction.

当你创建一个 def 时,你必须确保你的函数的域(this 和 args)和 codomain(result)之间存在正确的关系。

无论如何,不​​要犹豫输入(创建概念),它会帮助你推理你的代码。


为什么def user(userId: Int) :User不行?

Integer因为元素之间的关系User不存在。如果 UserIds 都是正整数,但您要求,该user(-10)怎么办?(这不会发生,对吧?)这个调用应该引发异常吗?还是返回 null ?

如果你认为它应该返回 null,然后返回一个 Option,它封装了潜在的缺失对应关系。

如果您认为它应该引发异常,则返回:

  • 一个Validation[SomethingRepresentingAnError, User](斯卡拉兹),
  • 一个Either[SomethingRepresentingAnError, User](scala 2.7, 2.8, 2.9)
  • Try[User](scala 2.10)

拥有丰富的返回类型将帮助您正确使用 API。

顺便说一句,Scala 不使用检查异常,因此您不能使用异常作为替代结果。应该为真正的异常行为保留异常(作为运行时异常)。

也可以看看 :

  • http://www.scala-lang.org/api/current/index.html#scala.util.control.Exception$
于 2013-01-29T18:30:55.130 回答
1

我认为在通过 id 获取数据时返回 Option[] 总是一个好主意。您无法确定具有此类 ID 的用户是否存在。例如。另一个请求已删除此用户或有人试图篡改您的输入数据。数据库是应用程序的外部系统,如果您知道如何从此类故障中恢复,那么您应该这样做。特别是在 Scala 中,Option 是完成此类任务的好工具。

于 2013-01-29T19:09:23.067 回答
1

Option是表示某些可能失败的计算的返回值的最简单的方式。只有在处理 Java 代码并且您的双手以某种方式被现有 API 束缚时(并且当您从 Java 代码调用代码时)才null可以接受抛出异常或返回。

下一步OptionEither[FailureIndication, SuccessValue].

进一步的改进是 ScalaZ 的Validation.

于 2013-01-29T21:44:40.930 回答