TypeScript 出现 Go 和 Rust的 错误? 没有Try/Catch?

JAVAScript 依靠抛出异常来处理错误,而 Go 和 Rust 将它们视为值 。你可能认为这没什么大不了的……但是,孩子,这可能听起来微不足道; 然而,它改变了游戏规则 。

TypeScript 出现 Go 和 Rust的 错误? 没有Try/Catch?

文章插图
那么,让我们从我的一些背景故事开始 。我是一名拥有大约十年经验的软件开发人员,最初使用 php,然后逐渐过渡到 JavaScript 。
大约五年前,我开始使用 TypeScript,从那时起,我就再也没有回到过 JavaScript 。当我开始使用它的那一刻,我认为它是有史以来最好的编程语言 。每个人都喜欢它; 每个人都用它……这只是最好的,对吧? 正确的? 正确的?
是的,然后我开始尝试其他语言,更现代的语言 。首先是 Go,然后我慢慢地将 Rust 添加到我的列表中(感谢 Prime) 。
当您不知道不同事物的存在时,就很难错过事物 。
我在说什么? Go 和 Rust 的共同点是什么? 错误 。对我来说最突出的事情 。更具体地说,这些语言如何处理它们 。
JavaScript 依靠抛出异常来处理错误,而 Go 和 Rust 将它们视为值 。你可能认为这没什么大不了的……但是,孩子,这可能听起来微不足道; 然而,它改变了游戏规则 。
让我们来看看它们 。我们不会深入研究每种语言; 我们想知道一般方法 。
让我们从 JavaScript/TypeScript 和一个小游戏开始 。
给自己五秒钟的时间来查看下面的代码并回答为什么我们需要将其包装在 try/catch 中 。
try {const request = { name: “test”, value: 2n };const body = JSON.stringify(request);const response = awAIt fetch("https://example.com", {method: “POST”,body,});if (!response.ok) {return;}// handle response} catch (e) {// handle errorreturn;}所以,我假设你们大多数人都猜到即使我们正在检查response.ok,fetch 方法仍然会抛出错误 。response.ok 仅“捕获”4xx 和 5xx 网络错误 。但当网络本身出现故障时,就会抛出错误 。
但我想知道有多少人猜到 JSON.stringify 也会抛出错误 。原因是请求对象包含bigint(2n)变量,JSON不知道如何字符串化 。
所以第一个问题是,就我个人而言,我认为这是有史以来最大的 JavaScript 问题:我们不知道什么会引发错误 。从 JavaScript 错误的角度来看,它与以下内容相同:
try {let data = https://www.isolves.com/it/cxkf/yy/js/2023-09-07/“Hello”;} catch (err) {console.error(err);}JavaScript 不知道; JavaScript 不在乎 。你应该知道 。
第二件事,这是完全可行的代码:
const request = { name: “test”, value: 2n };const body = JSON.stringify(request);const response = await fetch("https://example.com", {method: “POST”,body,});if (!response.ok) {return;}没有错误,即使这可能会破坏您的应用程序 。
现在,在我的脑海中,我可以听到,“有什么问题,只要在任何地方使用 try/catch 就可以了 。” 第三个问题来了:我们不知道抛出的是哪一个 。当然,我们可以通过错误消息进行猜测,但是对于有很多可能发生错误的地方的更大的服务/功能呢? 您确定通过一次 try/catch 正确处理了所有这些问题吗?
好吧,是时候停止对 JS 的挑剔,转向其他的事情了 。让我们从这段 Go 代码开始:
f, err := os.Open(“filename.ext”)if err != nil {log.Fatal(err)}// do something with the open *File f我们正在尝试打开一个返回文件或错误的文件 。您会经常看到这种情况,主要是因为我们知道哪些函数总是返回错误 。你永远不会错过任何一个 。这是将错误视为值的第一个示例 。您指定哪个函数可以返回它们,您返回它们,您分配它们,您检查它们,您使用它们 。
它也没有那么丰富多彩,这也是 Go 受到批评的事情之一——“错误检查代码”,其中 if err != nil { .... 有时需要比其他代码行更多的代码 。
if err != nil {…if err != nil {…if err != nil {…}} }if err != nil {… }…if err != nil {… }仍然完全值得付出努力,相信我 。
最后,铁锈:
let greeting_file_result = File::open(“hello.txt”);let greeting_file = match greeting_file_result {Ok(file) => file,Err(error) => panic!("Problem opening the file: {:?}", error),};这里显示的三个中最冗长的一个,具有讽刺意味的是,也是最好的一个 。因此,首先,Rust 使用其令人惊叹的枚举来处理错误(它们与 TypeScript 枚举不同!) 。无需详细介绍,这里重要的是它使用一个名为 Result 的枚举,它有两个变体:Ok 和 Err 。正如您可能猜到的,Ok 保存一个值,Err 保存……令人惊讶的是,一个错误:D 。


推荐阅读