ESS多版本 【ESS】11 Blocks 和 Procs

11: Blocks 和 Procs​

代码块和 Procs 提供了灵活且强大的方法来封装和传递代码。

Blocks​

一个代码块是一个匿名代码段,可以与方法一起使用。你可以在方法定义中使用 yield 关键字来执行传递给方法的块。

Ruby:
def greet
  yield
end

greet { print "Hello, world!" } # 输出 "Hello, world!"

你也可以传递带参数的块:

Ruby:
def greet
  yield("Ruby")
end

greet { |name| print "Hello, #{name}!" } # 输出 "Hello, Ruby!"

使用 yield 的优势​

yield 的优势在于它允许你在方法中执行任意代码,而不需要显式地将其作为参数传递。这使得方法更加灵活和动态。

Ruby:
def calculate
  result = yield(5, 10)
  print "Result: #{result}"
end

calculate { |a, b| a + b } # 输出 "Result: 15"
calculate { |a, b| a * b } # 输出 "Result: 50"

检查块是否存在​

使用 block_given? 方法可以检查块是否存在,以避免在没有块的情况下调用 yield 引发错误。

Ruby:
def greet
  if block_given?
    yield
  else
    print "Hello!"
  end
end

greet { print "Hi there!" } # 输出 "Hi there!"
greet # 输出 "Hello!"

Procs​

Proc 对象是一个封装了代码块的对象,可以在不同的上下文中多次调用。你可以使用 Proc.new 或 proc 方法创建一个 Proc 对象。

Ruby:
my_proc = Proc.new { print "Hello from Proc!" }
my_proc.call # 输出 "Hello from Proc!"

带参数的 Procs​

你可以创建带参数的 Proc 对象,并在调用时传递参数。

Ruby:
my_proc = Proc.new { |name| print "Hello, #{name}!" }
my_proc.call("Ruby") # 输出 "Hello, Ruby!"

将块转换为 Proc​

你可以使用 & 操作符将一个块转换为 Proc,并将其传递给另一个方法。

Ruby:
def greet(&block)
  block.call("Ruby")
end

greet { |name| print "Hello, #{name}!" } # 输出 "Hello, Ruby!"

Lambda​

lambda 是一种特殊类型的 Proc,它的行为与普通的 Proc 略有不同。使用 lambda 关键字创建。

Ruby:
my_lambda = lambda { print "Hello from Lambda!" }
my_lambda.call # 输出 "Hello from Lambda!"

Lambda 和 Proc 的区别​

  1. 参数检查:lambda 会严格检查参数个数,而 Proc 则不会。
  2. 返回行为:lambda 返回时仅从当前块返回,而 Proc 会返回整个方法。
Ruby:
my_proc = Proc.new { return "From Proc" }
def call_proc
  result = my_proc.call
  print "Result: #{result}" # 不会执行
end
# call_proc # 直接从方法中返回

my_lambda = lambda { return "From Lambda" }
def call_lambda
  result = my_lambda.call
  print "Result: #{result}" # 输出 "Result: From Lambda"
end
call_lambda
 

在线成员

论坛统计

主题
474
消息
2,137
成员
2,909
最新成员
小灵喵~