Ruby Lambda #

一、Lambda概述 #

Lambda是Ruby中的一种特殊Proc,具有更严格的参数检查和不同的返回行为。

二、创建Lambda #

2.1 lambda关键字 #

ruby
my_lambda = lambda { |n| n * 2 }
my_lambda.call(5)

2.2 箭头语法 #

ruby
my_lambda = ->(n) { n * 2 }
my_lambda.call(5)

my_lambda = -> n { n * 2 }
my_lambda.call(5)

multi_line = ->(a, b) {
  result = a + b
  result * 2
}
multi_line.call(1, 2)

2.3 无参数Lambda #

ruby
say_hello = -> { "Hello, World!" }
say_hello.call

say_hello = -> { puts "Hello" }
say_hello.call

2.4 默认参数 #

ruby
greet = ->(name = "World") { "Hello, #{name}!" }
greet.call
greet.call("Ruby")

三、调用Lambda #

3.1 call方法 #

ruby
double = ->(n) { n * 2 }
double.call(5)

3.2 []语法 #

ruby
double = ->(n) { n * 2 }
double[5]

3.3 .()语法 #

ruby
double = ->(n) { n * 2 }
double.(5)

3.4 ===语法 #

ruby
is_even = ->(n) { n.even? }
is_even === 4
is_even === 5

case 4
when is_even then "偶数"
else "奇数"
end

四、Lambda vs Proc #

4.1 参数检查 #

ruby
my_lambda = ->(a, b) { a + b }
my_proc = Proc.new { |a, b| a + b }

my_lambda.call(1, 2)
my_lambda.call(1)
my_lambda.call(1, 2, 3)

my_proc.call(1, 2)
my_proc.call(1)
my_proc.call(1, 2, 3)

4.2 返回行为 #

ruby
def test_lambda
  my_lambda = -> { return "lambda返回" }
  my_lambda.call
  "方法继续执行"
end

def test_proc
  my_proc = Proc.new { return "proc返回" }
  my_proc.call
  "这行不会执行"
end

test_lambda
test_proc

4.3 总结对比 #

特性 Lambda Proc
参数检查 严格 宽松
return行为 返回lambda 返回 enclosing 方法
类型 Proc子类 Proc
ruby
my_lambda = -> {}
my_proc = Proc.new {}

my_lambda.class
my_proc.class

my_lambda.lambda?
my_proc.lambda?

五、闭包 #

5.1 捕获变量 #

ruby
def create_counter
  count = 0
  -> { count += 1 }
end

counter = create_counter
counter.call
counter.call
counter.call

5.2 共享变量 #

ruby
def create_pair
  value = 0
  [
    -> { value += 1 },
    -> { value -= 1 },
    -> { value }
  ]
end

inc, dec, get = create_pair
inc.call
inc.call
get.call
dec.call
get.call

5.3 延迟执行 #

ruby
def lazy_evaluation
  expensive_value = nil
  -> {
    expensive_value ||= calculate_expensive_value
  }
end

lazy = lazy_evaluation
lazy.call
lazy.call

六、Lambda作为参数 #

6.1 基本用法 #

ruby
def process(value, processor)
  processor.call(value)
end

double = ->(n) { n * 2 }
process(5, double)

process(5, ->(n) { n ** 2 })

6.2 高阶函数 #

ruby
def compose(f, g)
  ->(x) { f.call(g.call(x)) }
end

double = ->(n) { n * 2 }
increment = ->(n) { n + 1 }

double_then_increment = compose(increment, double)
double_then_increment.call(5)

increment_then_double = compose(double, increment)
increment_then_double.call(5)

6.3 柯里化 #

ruby
def curry(f)
  ->(a) { ->(b) { f.call(a, b) } }
end

add = ->(a, b) { a + b }
curried_add = curry(add)

add_five = curried_add.call(5)
add_five.call(3)
add_five.call(10)

七、实用示例 #

7.1 过滤器 #

ruby
def create_filter(&condition)
  ->(items) { items.select(&condition) }
end

even_filter = create_filter(&:even?)
even_filter.call([1, 2, 3, 4, 5, 6])

positive_filter = create_filter { |n| n > 0 }
positive_filter.call([-1, 0, 1, 2, -3])

7.2 验证器 #

ruby
VALIDATORS = {
  email: ->(s) { s.match?(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i) },
  phone: ->(s) { s.match?(/\A\d{11}\z/) },
  age: ->(n) { n.is_a?(Integer) && n >= 0 && n <= 150 }
}

def valid?(type, value)
  VALIDATORS[type].call(value)
end

valid?(:email, "user@example.com")
valid?(:phone, "12345678901")
valid?(:age, 30)

7.3 事件处理 #

ruby
class EventHandler
  def initialize
    @handlers = {}
  end

  def on(event, &handler)
    @handlers[event] ||= []
    @handlers[event] << ->(*args) { handler.call(*args) }
  end

  def trigger(event, *args)
    @handlers[event]&.each { |h| h.call(*args) }
  end
end

handler = EventHandler.new
handler.on(:save) { |data| puts "Saving: #{data}" }
handler.on(:save) { |data| log("Saved: #{data}") }
handler.trigger(:save, { name: "Ruby" })

7.4 延迟初始化 #

ruby
class LazyValue
  def initialize(&block)
    @block = block
    @computed = false
    @value = nil
  end

  def value
    unless @computed
      @value = @block.call
      @computed = true
    end
    @value
  end

  def computed?
    @computed
  end
end

lazy = LazyValue.new { expensive_computation }
lazy.computed?
lazy.value
lazy.computed?

7.5 策略模式 #

ruby
class PriceCalculator
  STRATEGIES = {
    normal: ->(price) { price },
    discount: ->(price) { price * 0.9 },
    vip: ->(price) { price * 0.8 },
    sale: ->(price) { price * 0.5 }
  }

  def initialize(strategy = :normal)
    @strategy = STRATEGIES[strategy]
  end

  def calculate(price)
    @strategy.call(price)
  end
end

calculator = PriceCalculator.new(:vip)
calculator.calculate(100)

八、最佳实践 #

8.1 选择Lambda还是Proc #

ruby
my_lambda = ->(x) { x * 2 }

my_proc = Proc.new { |x| x * 2 }

def with_callback(&callback)
  callback.call
end

8.2 使用箭头语法 #

ruby
double = ->(n) { n * 2 }

double = lambda { |n| n * 2 }

8.3 参数命名 #

ruby
process = ->(input, options: {}) do
  transform(input, options)
end

process = ->(data, config) { transform(data, config) }

九、总结 #

本章我们学习了:

  1. 创建Lambda:lambda关键字、箭头语法
  2. 调用Lambda:call、[]、.()、===
  3. Lambda vs Proc:参数检查、返回行为
  4. 闭包:捕获变量、延迟执行
  5. 高阶函数:compose、curry
  6. 实用场景:过滤器、验证器、策略模式

接下来让我们学习Ruby的作用域!

最后更新:2026-03-27