elm';s编译不同于Java';是否检查异常?
elm';s编译不同于Java';是否检查异常?,java,elm,checked-exceptions,Java,Elm,Checked Exceptions,elm的索赔是其主要卖点之一(见) 但是如果你停下来想一想,没有什么能阻止你被零除或者耗尽内存 elm编译器的基本功能是强制您覆盖所有可能导致异常的路径 例如: import String exposing (toInt) toIntOrZero s = case toInt s of Err e -> 0 Ok val -> val 但是这与java中的“检查异常”功能有什么不
elm
的索赔是其主要卖点之一(见)
但是如果你停下来想一想,没有什么能阻止你被零除或者耗尽内存
elm
编译器的基本功能是强制您覆盖所有可能导致异常的路径
例如:
import String exposing (toInt)
toIntOrZero s = case toInt s of
Err e -> 0
Ok val -> val
但是这与java
中的“检查异常”功能有什么不同呢
public static Integer toIntOrZero(String s) {
try { return Integer.valueOf(s); }
catch (NumberFormatException e) { return 0; }
}
我从来没有听说过有人声称
java
是一种零运行时异常语言。请不要过于沉迷于本质上的营销夸张。当然,有些类错误是任何编译器都无法完全排除的
因此,我一直对这些零运行时异常声明持保留态度,但我认为我理解支持者的意图。Elm是作为Javascript开发前端应用程序的替代品而创建的,Javascript是一个混乱的世界,例外情况比比皆是,只是日常生活的一部分。Elm会让你更难自食其力,而且如果你在应用程序上运行基本的健全性测试,你可能永远不会在生产中出现运行时异常
Elm从几个方面大大降低了异常的可能性
Debug.crash
,该语言中没有可丢弃异常的概念,顾名思义,它实际上应该只用于调试和清除不完整的逻辑路径
由于没有可丢弃的异常,因此处理问题通常是通过Result
和Maybe
等类型完成的
这可以被认为是对Java的检查异常的松散分析,但从概念上讲,它们与我感觉非常不同。让我们面对现实吧。例外情况被滥用。您提到了Java中的一个示例,其中Integer.valueOf()
表示它将返回一个int,但如果您传递其他任何内容,它将展开堆栈并冒泡,直到某个函数有望捕获它。这让我感觉非常混乱,当然,检查过的异常可以帮助减少故障传播的窗口,但潜在的事实是,异常对于业务逻辑来说是错误的工具
抛出异常的另一种方法是让类与结果
和可能
Elm类型相关联,但在Java早期,这几乎不可能做到干净,即使使用泛型,编写此类类型也比Elm类型的简单性更繁琐,更容易出错。由于Elm的封闭式系统
\uuu
结束所有case语句来选择不进行穷举模式匹配,但那只是对语言的愚蠢滥用。这些检查是为了帮助您,我觉得更安全的事实是,我没有选择在Elm中进行错误检查-默认情况下它就在那里
最后,运行时异常仍然是可能的(例如:处理由递归JSON解码器定义引起的众所周知的运行时异常),每当我听到有人说不可能在Elm中获得异常时,我都会有些畏缩。事实上,异常是可能的,但在日常Javascript开发中遇到的几乎所有异常在Elm中都是不可能的。正如一位评论员所指出的,Java有未经检查的异常,因此运行时错误确实会发生。Elm也有未经检查的例外情况,比如被零除,但去掉了在实践中最常见的例外情况。正如Chad的回答所提到的,Elm的
可能
/结果
类型在实践中的工作方式与Java的检查异常非常不同。一个有经验的Elm程序员不会编写像toIntOrZero
这样的函数(如果编写了,他们可能不会使用case…of
,而是更喜欢像toIntOrZero=String.toInt>>Result.with default 0
)
将多个操作与Result.map
、Result.和等链接在一起,提供了一种非常有表现力的方法来处理错误案例,而不必强迫程序员深陷其中。例如,如果我们想编写一个函数,通过将ID转换为Int来验证ID,在某些数据结构中查找它(当它可能不存在时),然后验证与该用户关联的某些属性,我们可以编写如下内容:
lookupUser : Int -> Result String User
lookupUser intId = ...
userInGoodStanding : User -> Bool
userInGoodStanding user = ...
isValidId : String -> Bool
isValidId id =
String.toInt id
|> Result.andThen lookupUser
|> Result.map userInGoodStanding
|> Result.withDefault False
这是这样写的,“将ID转换为int,然后查找相关的用户,然后验证用户,如果有任何失败,则返回False。”您的里程可能会有所不同,但一旦您习惯了它,我(我想还有许多Elm程序员!)会发现这是一种非常好的编写代码的方法,对错误具有鲁棒性。Java仍然存在未检查的异常。充其量你可以说Java“具有成为零运行时异常语言的能力。公平的观点是,elm
是一种