Scala 是否与已检查异常等效?

Scala 是否与已检查异常等效?,scala,functional-programming,Scala,Functional Programming,从Scala开始,阅读关于或的内容,我自然会将新概念与我所知道的东西(在本例中是Java)进行比较。检查异常的概念与或是否有任何区别 在这两种情况下 方法中明确说明了失败的可能性(抛出或返回) 当错误发生时,程序员可以直接处理它或将其向上移动(再次返回或) 有一种方法可以通知调用者错误的原因 我想我们可以使用上的理解来编写代码,因为不会有类似于检查异常的错误 我想知道我是否是唯一一个有问题看到差异的初学者 谢谢这两个都可以用于除异常之外的其他用途。例如,如果要让用户为您键入输入或指定包含该输

从Scala开始,阅读关于
的内容,我自然会将新概念与我所知道的东西(在本例中是Java)进行比较。检查异常的概念与
是否有任何区别

在这两种情况下

  • 方法中明确说明了失败的可能性(
    抛出
    或返回
  • 当错误发生时,程序员可以直接处理它或将其向上移动(再次返回
  • 有一种方法可以通知调用者错误的原因
  • 我想我们可以使用
    上的理解来编写代码,因为不会有类似于检查异常的错误

    我想知道我是否是唯一一个有问题看到差异的初学者


    谢谢

    这两个
    都可以用于除异常之外的其他用途。例如,如果要让用户为您键入输入或指定包含该输入的文件,则可以将其表示为
    或[String,file]

    通常用于异常处理。
    other
    与选中异常之间的主要区别在于
    other
    的控制流始终是显式的。编译器真的不会让你忘记你正在处理一个
    或者
    ;它不会在您不知道的情况下从多个地方收集
    ,返回的所有内容都必须是
    ,等等。。因此,您可以使用
    来控制程序执行,而不是在可能出现异常情况时使用。而且,
    或者
    都不能捕获堆栈跟踪,这使得它比典型的异常更有效

    另一个区别是异常可以用于控制流。需要跳出三个嵌套循环吗?没问题——抛出一个异常(没有堆栈跟踪)并在外部捕获它。需要跳出五个嵌套方法调用吗?没问题!两者都不提供类似的服务

    也就是说,正如你所指出的,有很多相似之处。您可以传回信息(尽管
    使其变得微不足道,而选中的异常则使您编写自己的类来存储所需的任何额外信息);您可以将
    打开或折叠成其他内容,等等


    因此,总而言之:尽管在显式错误处理方面,您可以使用
    和检查异常来完成相同的任务,但它们在实践中是相对不同的。特别是,
    或者
    使得创建和传回不同的状态变得非常容易,而选中的异常则擅长绕过所有正常的控制流,希望能够返回到可以合理处理异常情况的地方。

    是的,
    或者
    都是在语言中嵌入异常的一种方式;一组可能失败的操作可能会向某个非本地站点抛出错误值

    除了Rex提到的实际问题之外,您还可以从
    的简单语义中获得一些额外的东西:

    • 形成单子;因此,您可以对计算结果为
      的表达式集使用一元运算。例如,用于短路评估,无需测试结果
    • 或者
      在类型中—因此,仅类型检查器就足以跟踪值的错误处理

    一旦您能够返回错误消息
    (左s)
    或成功返回值
    Right v
    ,您就可以在顶部分层异常,就像前面所做的那样,只要
    加上一个错误处理程序。

    就返回签名而言,这两者都相当于选中的异常。结果可以是抛出异常X或a。但是,抛出异常并不等同于返回异常——第一个异常在引用上是不透明的

    如果Scala的或不是(截至2.9),则等价于返回类型是正偏差的,并且需要努力提取/解构异常,或是无偏差的;您需要显式地请求left或right值。这是一个,并且在实践中有一点痛苦-考虑以下三个调用来产生方法< /P>
    for {
      a <- eitherA("input").right
      b <- eitherB(a).right
      c <- eitherC(b).right
    } yield c // Either[Exception, C]
    
    用于{
    
    a谢谢。这很有趣,因为我看到的几乎所有示例都在讨论错误处理。不幸的是,我无法从教程中讨论您提到的其他案例。此外,如果您处理一系列内容,比如一系列带有验证功能的电子邮件,并从该功能捕获异常,整个列表将失败(如果您将catch块放置在循环之外的某个位置)。在任何一种情况下,您都可以收集所有错误,而不仅仅是第一个错误。控制流的异常不是反模式的吗?@om nom nom-因此,请将catch块放置在循环中(或在Eithers上查看地图)。这不是一个根本性的区别。这也是一个优点,我可以将返回/获取其中一个的函数链接起来,但我不能在异常情况下这样做,因为它们会“破坏”链?@ManuelSchmidt-您可以使用
    和异常进行链接。使用
    进行链接的工作稍微少一点。好的评论,但您怎么看引用透明意味着?引用透明意味着我们可以用它的值替换表达式–抛出的异常是一种副作用,它不能转换为值。左[SomeException]的任一值都不会抛出,因此是引用透明的。这里可以找到一个很好的解释: