首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在scala中使用异常是一种不好的做法吗?

在scala中使用异常是一种不好的做法吗?
EN

Stack Overflow用户
提问于 2012-10-22 13:06:56
回答 3查看 4.8K关注 0票数 24

我多次看到scala代码使用选项(简单值)或[ListError,T]来处理错误。

这就让位于这样的代码

代码语言:javascript
复制
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)
        )
      }
    )
  }
)

这就产生了一个不太好的代码嵌套,迫使您在每一步都要处理失败,并且强制您的所有函数返回一个任一个.

所以我想知道

  • scala (或一般的函数式编程)中不鼓励使用异常。
  • 使用它们有任何缺点(关于不可变或代码并发)。
  • 异常在某种程度上与原则或函数式编程相冲突。
  • 您可以想出一种更好的方法来编写给定的示例。

--

在使用return语句发现错误时,可以通过退出函数来避免嵌套,但scala中也不鼓励使用返回.

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-22 13:40:33

下面的版本使用的事实是,Either的正确投影是一个monad,并且与您的代码完全等价:

代码语言:javascript
复制
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之后的代码:

代码语言:javascript
复制
def createApplicationToken(accessToken: AccessToken) = for {
   info <- retrieveProviderInfo(accessToken)
   user <- User.findOrCreateFromProviderInfo(info)
   refr <- user.refreshApplicationToken
} yield refr.token
票数 25
EN

Stack Overflow用户

发布于 2012-10-22 14:05:38

正如om-nom所说,我问了一个类似的问题:Throwing exceptions in Scala, what is the "official rule"

但这并不是我唯一想让你感兴趣的,因为我曾经用大量的样板代码和大量的缩进级别来编写代码,因为模式匹配等等。

票数 6
EN

Stack Overflow用户

发布于 2012-10-22 15:07:09

什么是理想,什么是实际,答案各不相同。理想情况下,避免使用异常。实际上,没有他们你就活不下去了。

Scala似乎倾向于单行程序,并且按照这些思路,v2.10已经尝试了新的单行。

代码语言:javascript
复制
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% instead
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13012149

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档