MST

星途 面试题库

面试题:Ruby中块、Proc和Lambda的基本区别

请简要阐述Ruby中块(block)、Proc对象和Lambda的主要区别,包括它们在语法、参数处理和返回值方面的差异。
28.1万 热度难度
编程语言Ruby

知识考点

AI 面试

面试题答案

一键面试

语法差异

  • 块(block)
    • 没有独立的定义语法,总是附属在方法调用之后。例如:
(1..5).each do |num|
  puts num
end
  • 通常用do...end 或者{} 来表示。do...end 一般用于多行代码块,{} 一般用于单行代码块。
  • Proc对象
    • 通过Proc.new 或者lambda 关键字创建(虽然lambda 创建的严格来说是Proc 的子类Lambda,但Proc.new 是最常见创建Proc 对象的方式)。例如:
proc_obj = Proc.new { |param| puts param }
  • Lambda
    • 使用lambda 关键字创建。例如:
lambda_obj = lambda { |param| puts param }

参数处理差异

  • 块(block)
    • 块没有自己独立的参数列表,它依赖于调用它的方法来传递参数。例如each 方法传递给块的参数就是数组中的每个元素。
    • 不检查传递的参数数量,即使方法传递的参数与块预期处理的参数数量不匹配,也不会报错(在方法内部会按照块的逻辑执行,多余参数会被忽略,缺少参数不会引发参数相关错误)。
  • Proc对象
    • 定义时可以指定参数,调用时不严格检查参数数量。例如:
proc_obj = Proc.new { |a, b| puts a + b }
proc_obj.call(1) # 不会报错,b为nil
proc_obj.call(1, 2, 3) # 不会报错,3被忽略
  • Lambda
    • 严格检查参数数量。如果传递的参数数量与定义时不一致,会抛出ArgumentError。例如:
lambda_obj = lambda { |a, b| puts a + b }
lambda_obj.call(1) # 抛出ArgumentError: wrong number of arguments (given 1, expected 2)
lambda_obj.call(1, 2, 3) # 抛出ArgumentError: wrong number of arguments (given 3, expected 2)

返回值差异

  • 块(block)
    • 使用return 关键字会导致包含该块的方法立即返回,而不是块本身返回。例如:
def test_block
  (1..3).each do |num|
    return num if num == 2
  end
  return -1
end
puts test_block # 输出2
  • Proc对象
    • 使用return 关键字会导致Proc 对象所在的方法返回(和块类似)。例如:
def test_proc
  proc_obj = Proc.new { return 10 }
  proc_obj.call
  return -1
end
puts test_proc # 输出10
  • Lambda
    • 使用return 关键字只会从lambda 表达式本身返回,不会影响外部方法。例如:
def test_lambda
  lambda_obj = lambda { return 10 }
  lambda_obj.call
  return -1
end
puts test_lambda # 输出 -1