我多次看到scala代码使用选项(简单值)或[ListError,T]来处理错误。
这就让位于这样的代码
def createApplicationToken(accessToken: AccessToken): Either[List[Error], ApplicationToken] = {
// go to social info provider and fetch information
retrieveProviderInfo(accessToken).fold(
errors => Left(errors),
info => {
// try to find user using the info from the provider
// if it's not there, create user
User.findOrCreateFromProviderInfo(info).fold(
errors => Left(errors),
user => {
// try to create a fresh token and save it to the user
user.refreshApplicationToken.fold(
errors => Left(errors),
user => Right(user.token)
)
}
)
}
)这就产生了一个不太好的代码嵌套,迫使您在每一步都要处理失败,并且强制您的所有函数返回一个任一个.
所以我想知道
--
在使用return语句发现错误时,可以通过退出函数来避免嵌套,但scala中也不鼓励使用返回.
发布于 2012-10-22 13:40:33
下面的版本使用的事实是,Either的正确投影是一个monad,并且与您的代码完全等价:
def createApplicationToken(accessToken: AccessToken) = for {
info <- retrieveProviderInfo(accessToken).right
user <- User.findOrCreateFromProviderInfo(info).right
refr <- user.refreshApplicationToken.right
} yield refr.token在展示Either的优势方面做得更好。
更普遍地说,这些规则与Java中的规则相同:在特殊情况下使用异常。当您以这种方式工作时,您可能会发现您更改了例外的定义--例如,无效的用户输入并不是真正的例外,超时的网络请求并不是真正的例外,等等。
自Scala2.12以来的右偏Either
现在可以省略.right,因此以下代码相当于Scala2.12之后的代码:
def createApplicationToken(accessToken: AccessToken) = for {
info <- retrieveProviderInfo(accessToken)
user <- User.findOrCreateFromProviderInfo(info)
refr <- user.refreshApplicationToken
} yield refr.token发布于 2012-10-22 14:05:38
正如om-nom所说,我问了一个类似的问题:Throwing exceptions in Scala, what is the "official rule"
但这并不是我唯一想让你感兴趣的,因为我曾经用大量的样板代码和大量的缩进级别来编写代码,因为模式匹配等等。
发布于 2012-10-22 15:07:09
什么是理想,什么是实际,答案各不相同。理想情况下,避免使用异常。实际上,没有他们你就活不下去了。
Scala似乎倾向于单行程序,并且按照这些思路,v2.10已经尝试了新的单行。
import scala.util.Try
def percentCompleted( total:Int, done:Int ): Int = Try (done * 100 / total) getOrElse 100
percentCompleted( 0, 10 ) // Catches divide-by-zero and returns 100% insteadhttps://stackoverflow.com/questions/13012149
复制相似问题