gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 23:24:00 27 4
gpt4 key购买 nike

我见过很多次使用 Option(对于简单值)或 Either[List[Error], T] 来处理错误的 scala 代码。

这为这样的代码提供了位置

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)
)
}
)
}
)

这会产生不太好的代码嵌套,迫使您处理每一步的失败,并且还迫使您让所有函数返回 Either[...]

所以我想知道是否

  • 在 scala(或一般的函数式编程)中不鼓励使用异常

  • 使用它们有任何缺点(关于不变性或代码并发性)

  • 异常在某种程度上与函数式编程的原则相冲突

  • 您可以想出更好的方法来编写给定示例

--

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

最佳答案

以下版本使用 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 中的规则相同:在异常情况下使用异常。您可能会发现,当您以这种方式工作时,您对异常的定义做了一些更改,例如,无效的用户输入并不是真正的异常,超时的网络请求也不是真正的异常。特殊情况等

右偏 Either 自 Scala 2.12 起

您现在可以省略 .right,因此以下代码自 Scala 2.12 起是等效的:

def createApplicationToken(accessToken: AccessToken) = for {
info <- retrieveProviderInfo(accessToken)
user <- User.findOrCreateFromProviderInfo(info)
refr <- user.refreshApplicationToken
} yield refr.token

关于scala - 在 scala 中使用异常是一种不好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13012149/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com