Ruby ensure 关键字
最后修改日期:2025 年 4 月 27 日
本教程解释了如何使用 Ruby 的 ensure 关键字。ensure 子句保证代码的执行,无论是否发生异常。
ensure 关键字定义了一个块,该块总是在 begin 块之后执行,无论是否发生异常。它通常用于清理操作。
ensure 与 begin、rescue 和 else 关键字一起工作。它在正常执行或任何 rescue 块之后运行。即使您提前返回或引发另一个异常,代码也会执行。
基本的 ensure 示例
这个简单的示例演示了 ensure 的基本用法。无论是否发生异常,ensure 块都会运行。
begin
puts "Performing operation"
raise "Error occurred" if rand < 0.5
rescue => e
puts "Rescued: #{e.message}"
ensure
puts "This always runs"
end
ensure 块会在操作成功或失败时执行。这使其成为关闭文件或释放资源的清理任务的理想选择。
使用 ensure 进行文件处理
ensure 的一个常见用途是确保文件被正确关闭。本示例显示了即使发生异常,也进行了适当的文件处理。
begin
file = File.open("data.txt", "w")
file.puts "Writing important data"
raise "Disk error" if rand < 0.3
rescue => e
puts "Error writing file: #{e}"
ensure
if file
file.close
puts "File closed successfully"
end
end
文件保证会关闭,防止资源泄露。if file 检查确保我们不会尝试关闭一个从未打开的文件。
使用 ensure 进行数据库连接
数据库连接应始终正确关闭。本示例显示了 ensure 如何保证连接的清理。
require 'sqlite3'
begin
db = SQLite3::Database.new("test.db")
db.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)")
db.execute("INSERT INTO users (name) VALUES ('John')")
rescue SQLite3::Exception => e
puts "Database error: #{e}"
ensure
if db
db.close
puts "Database connection closed"
end
end
无论操作成功还是失败,数据库连接都会关闭。这可以防止可能耗尽数据库资源的连接泄露。
带 return 语句的 ensure
即使在方法中使用 return,ensure 块也会运行。本示例演示了这种行为。
def test_ensure
begin
puts "Starting method"
return "Early return" if rand < 0.5
puts "Normal execution"
ensure
puts "Ensure block executed"
end
end
puts test_ensure
ensure 块在方法返回之前运行。无论返回是提前发生的还是在正常执行结束时发生的,都会如此。
嵌套的 ensure 块
Ruby 允许使用带有自己的 ensure 子句的嵌套 begin 块。本示例显示了它们的执行顺序。
begin
puts "Outer begin"
begin
puts "Inner begin"
raise "Inner error" if rand < 0.5
ensure
puts "Inner ensure"
end
raise "Outer error" if rand < 0.5
rescue => e
puts "Rescued: #{e}"
ensure
puts "Outer ensure"
end
每个 ensure 块在其对应的 begin 块退出时运行。内部 ensure 在外部 ensure 之前运行,形成一个清理堆栈。
带线程的 ensure
线程中的 ensure 块在线程终止时执行,无论是正常终止还是由于异常终止。本示例演示了线程清理。
thread = Thread.new do
begin
puts "Thread working"
sleep 1
raise "Thread error" if rand < 0.5
ensure
puts "Thread cleanup"
end
end
thread.join
puts "Main program continues"
无论线程成功完成还是引发异常,线程的 ensure 块都会运行。这对于线程本地资源的清理至关重要。
在方法定义中使用 ensure
方法可以使用 ensure 而无需显式的 begin 块。本示例显示了方法级 ensure 的简写语法。
def process_data
puts "Processing data"
raise "Processing error" if rand < 0.4
rescue => e
puts "Error: #{e}"
ensure
puts "Cleanup resources"
end
process_data
整个方法体充当一个隐式的 begin 块。ensure 子句仍然保证执行,无论方法如何退出。
来源
本教程通过实际示例涵盖了 Ruby 的 ensure 关键字,展示了资源清理、线程安全和方法级保证。
作者
列出 所有 Ruby 教程。