Ruby yield 关键字
最后修改日期:2025 年 4 月 27 日
本教程将解释如何使用 Ruby 的 yield 关键字。yield 关键字是与 Ruby 中的代码块交互的基础。
yield 关键字将控制权从方法转移到其关联的代码块。它允许方法接受可以在方法上下文中执行的代码块。
带有 yield 的代码块支持迭代、资源管理和回调等强大模式。它们是 Ruby 表达性语法的一个关键特性。
基础 yield 示例
这个简单的示例演示了 yield 关键字的基本用法。该方法将控制权交给其代码块。
def greet
puts "Before yield"
yield
puts "After yield"
end
greet { puts "Hello from the block!" }
yield 关键字执行传递给 greet 方法的代码块。输出显示了方法和代码块之间的执行流程。
向 yield 传递参数
yield 可以将参数传递给其代码块。代码块在竖线 | | 之间接收这些参数。
def calculate(a, b)
puts "Calculating..."
result = yield(a, b)
puts "Result: #{result}"
end
calculate(5, 3) { |x, y| x * y }
calculate(10, 2) { |x, y| x / y }
该方法通过 yield 将参数传递给代码块。不同的代码块可以使用相同的参数执行不同的操作。
使用 block_given? 检查代码块
使用 yield 的方法应该检查是否提供了代码块。block_given? 方法可以防止在没有代码块时出现错误。
def process
if block_given?
yield
else
puts "No block provided"
end
end
process { puts "Processing..." }
process
第一次调用执行代码块,第二次则优雅地处理了缺少代码块的情况。这使得方法更加健壮。
实现自定义迭代器
yield 支持创建自定义迭代器。此示例模仿了 Ruby 的数组 each 方法。
def my_each(array)
i = 0
while i < array.length
yield(array[i])
i += 1
end
array
end
my_each([1, 2, 3]) { |x| puts x * 2 }
该方法将数组的每个元素 yield 给代码块。代码块处理每个元素,展示了 Ruby 内置迭代器的工作原理。
资源管理模式
yield 非常适合资源管理模式。这可以确保资源被正确地分配和释放。
def with_file(filename)
file = File.open(filename, 'w')
yield(file)
ensure
file.close if file
end
with_file('output.txt') do |f|
f.puts "First line"
f.puts "Second line"
end
该方法负责文件的打开和关闭,而代码块负责写入内容。ensure 子句保证即使发生错误,文件也会被关闭。
Yield 配合多个代码块
方法可以多次 yield 同一个代码块。这可以创建灵活的执行模式。
def stages
puts "Stage 1"
yield("start")
puts "Stage 2"
yield("middle")
puts "Stage 3"
yield("end")
end
stages { |phase| puts "Processing #{phase} phase" }
该方法在不同阶段 yield 控制权,并传递阶段信息。代码块会执行多次,并带有不同的参数。
进阶:Yield 配合 Enumerator
这个进阶示例展示了 yield 如何创建枚举器。这使得序列的延迟计算成为可能。
def fibonacci_sequence
return enum_for(:fibonacci_sequence) unless block_given?
a, b = 0, 1
loop do
yield a
a, b = b, a + b
end
end
# Get first 10 Fibonacci numbers
fibonacci_sequence.take(10).each { |x| puts x }
该方法会无限生成斐波那契数列。如果不提供代码块,它将返回一个用于延迟计算的枚举器。如果提供了代码块,它将 yield 每个数字。
来源
本教程通过实际示例讲解了 Ruby 的 yield 关键字,展示了代码块、迭代器、资源管理和枚举器。
作者
列出 所有 Ruby 教程。