ruby、Python 以及 Swift 语言关于 “Finally” 实现的趣谈

0. 概览

结构化代码语义是任何语言入门之必备基本功,想写出"意大利面条"似的美味代码么?直接干就对了!

虽然上面有些"话糙理不糙",但不可否认的是现今几乎所有高级语言都对代码结构化语义提供了良好的支持。入门码农们的第一课都是先从顺序执行、跳转、条件走偏开始学起。

在顺序执行的结构化代码中,如果之前申请了资源,怎么确保随后无论发生什么事它们都可以被正确释放呢?

在本篇博文中,您将了解到如下内容:

  1. 什么是 "Finally" ?
  2. 从 ruby 谈起
  3. Python 中的实现
  4. "格格不入"的 Swift
  5. 轻量级 Finally 语法糖

有点"兴奋"了吗?那还等什么?

Let's go!!!;)


1. 什么是 "Finally" ?

Finally 这个词很形象!它像一个会发出声音的感叹词:谢天谢地,这一切终于结束了!你终于来了!

一段代码在执行中可能出现各种意外情况:参数错误、文件损坏、有异常抛出、处理器罢工、新买的 M3 Max 纯黑丝 MBP 爱机变心了...

如果我们在代码中创建了一些资源,怎么确保在上面这些情况发生时它们还可以被正确释放掉呢?

ruby 复制代码
#!/usr/bin/ruby

file = File.open("lazy.rb")
r = 1..63
for a in r do
    // 可能的抛出异常点:内存不足!
    for b in r do
        // 可能的抛出异常点:处理器罢工!
        for c in r do
            // 可能的抛出异常点:爱机抑郁!
            for d in r do
                // 可能的抛出异常点:...
                if a + b + c + d == 63
                    rlt = a*b + b*c + c*d
                    if rlt >= max 
                        max = rlt
                        file.puts(max)
                    end
                end
            end
        end
    end
end

print("max is #{max}\n")

比如在上面的 ruby 代码里,我们崎岖前行中的代码可能会遇到各种"艰难险阻",那么一旦"祸从天降"如何保证开头的 file 对象占据的资源被释放呢?

上帝说:要有 Finally ! 于是乎,Finally 机制应运而生了!

Finally 就是一位"超级保姆"、一位技术高超的 Cleaner!不管之前是多么的一塌糊涂,只要一经它手收拾就会变得的"窗明几净",任何之前残留的痕迹都将一去不复返,正所谓:"两岸猿声啼不住,轻舟已过万重山!呜呼哉!"

Finally 是结构化开发中一道靓丽的"屏障",不管发生神马,Finally 块中的代码一定会被执行!(你们确定一定以及肯定?)

2. 从 ruby 谈起

首先,我们来看看 ruby 对 Finally 的支持。(不知为何看到 ruby 总有种要发财的赶脚...金银财宝快过来...)

ruby 中使用 ensure 语句块来支持 Finally 的语义:

ruby 复制代码
begin
file = File.open("lazy.rb")
# 其它可能会抛出异常的其它操作...
ensure
file.close
puts("文件已被释放!")
end

看到了吗?我就是不缩进!!!Python 你咬我啊!:)

当然,我们还可以加入 rescue 子句来处理异常:

ruby 复制代码
begin
file = File.open("lazy.rb")
# 其它可能会抛出异常的其它操作...
rescue
puts("ERR: #{$!}")
ensure
file.close
puts("文件已被释放!")
end

3. Python 中的实现

不知 ruby 和 Python 这哥俩到底是谁"抄袭"的谁,Python 对 Finally 的实现几乎与 ruby 毫无二致:

python 复制代码
f = None 
try:
    f = open("lazy.txt")
    # 可能有其它"惊喜"等待着我们,但我们不怕!:)
except IOError:
    print("无法打开 lazy.txt 文件")
except KeyboardInterrupt:
    print("用户终止了输入,可能是因为着急去交水费!")
finally:
    if f:
        f.close()
    print("成功关闭文件!")

从如上代码中可以发现,除了将 rescue 变为 except、把 ensure 改为 finally 一切几乎都没啥区别。

当然,还有层层缩进仿佛在诉说着什么...

4. "格格不入"的 Swift

如果说 ruby 和 Python 有点像兄弟俩,那么 Swift 更像一只"莫名其妙"的燕子(这句话更莫名其妙)。

有点"出乎意料"的是,在 Swift 语言中我们使用 defer 关键字来保证一段语句块中必须被 Finally 清理掉的内容:

swift 复制代码
func read() -> String {
    
    let file = File.open(...)
    
    defer {
        file.close()
    }
    
    do {
        return try file.readlines.join("\n")
    } catch {
        print("ERR: \(error)")
    }
}

如上代码所示,不管最后代码流以何种方式离开 read() 方法,defer 语句块中的内容都会被执行!

5. 轻量级 Finally 语法糖

其实对于简单的 Finally 实现,ruby 和 Python 都支持更便捷的语法。

比如在 ruby 中我们可以在文件打开的附庸闭包中处理文件,当闭包结束时文件对象自然"灰飞烟灭":

ruby 复制代码
File.open("lazy.rb") {|file| file.readlines}

而在 Python 中也有对应的 with 语句欲"乘风而去":

python 复制代码
with open("lazy.txt") as file:
    for line in file:
        print(line, end='')

在上面两段代码片段中,被打开的 file 永远无法逃出其最终的宿命,一切尽在不言中!

那么,看到这里小伙伴们对哪种语言中 Finally 的实现更情有独钟呢?


喜欢这种天马行空无厘头写作风格的小伙伴们,请到如下链接观赏更"刺激"的文章:

请做好准备不要惊掉下巴哦!


总结

在本篇博文中,我们讨论了 ruby、Python 和 Swift 语言中对 Finally 机制的不同实现,并用诸多代码片段来演示它们实际的使用,小伙伴们值得拥有!

感谢观赏,再会!8-)

相关推荐
HarderCoder20 分钟前
Swift 6 实战:从“定时器轮询”到 AsyncSequence 的优雅实时推送
swift
lapiii3582 小时前
[智能体设计模式] 第4章:反思(Reflection)
人工智能·python·设计模式
快乐非自愿3 小时前
Java垃圾收集器全解:从Serial到G1的进化之旅
java·开发语言·python
Daniel_Coder6 小时前
iOS Widget 开发-9:可配置 Widget:使用 IntentConfiguration 实现参数选择
ios·swiftui·swift·widget·intents
百锦再6 小时前
第11章 泛型、trait与生命周期
android·网络·人工智能·python·golang·rust·go
zbhbbedp282793cl8 小时前
如何在VSCode中安装Python扩展?
ide·vscode·python
非专业程序员Ping8 小时前
Vibe Coding 实战!花了两天时间,让 AI 写了一个富文本渲染引擎!
ios·ai·swift·claude·vibecoding
Python私教10 小时前
Python 开发环境安装与配置全指南(2025版)
开发语言·python
百锦再10 小时前
第12章 测试编写
android·java·开发语言·python·rust·go·erlang
熠熠仔10 小时前
QGIS 3.34+ 网络分析基础数据自动化生成:从脚本到应用
python·数据分析