Ruby 小技巧(三) —— lamdba 的使用

关于 Lambda、Proc、和 Block 的区别网上已经有很多文章了,所以在这里就不过多赘述。这里讲讲一些关于 lambda 使用上的技巧。

Lambda 的创建方式

使用 lambda 语法

greeting = lambda { puts "Hello world" }

greeting.call 
# => hello world

print_something = lambda {  |something| puts something }

print_something.call("Hello ian")
# => Hello ian

buy = lambda do |something|
  puts "Buy #{something}"
end
buy.call("a computer")
# => Buy a computer

使用箭头语法

greeting = -> { puts "Hello world" }
greeting.call 
# => Hello world

print_something = -> (something) { puts something }
print_something.call("box")
# => box 

buy = -> (something) do
  puts "Buy #{something}"
end
buy.call("a computer")
# => Buy a computer

可以看出,使用箭头方法定义 lambda 时,参数的位置与直接使用 lambda 语法定义时有些不同。使用箭头方法定义时,参数放在块的外部;而使用 lambda 语法时,参数放在块的内部


多个参数

lambda 的定义支持多个参数

sum = lambda do |num1, num2|
  return num1 + num2
end
sum.call(1, 2)
# => 3

符号参数

lambda 的定义也支持符号参数

move = lambda do |from:, to:|
  puts "move from #{from} to #{to}"
end
move.call(from: "home", to: "company")

# => move from home to company

Lambda 的调用方式

第一种方式是使用 call 直接调用,上述的例子已经演示过了。下面介绍两种其他的调用方式

使用 [] 调用

box = lambda do |size|
  "box-#{size}"
end

box[:lg]            # => box-lg
box[:sm]          # => box-sm

使用这种方式可以在某些情况下可以提升代码的可读性


使用 === 调用

lambda#===lambda#call 的别名,所以上面的代码也可以写成这样

box = lambda { |size| "box-#{size}" }

box.===(:lg)        # => box-lg
box.===(:sm)          # => box-sm

但是在这个例子中,这种用法并没带来什么好处,这种方法真正的用处是作为 case 的条件句。case 在对比传入的值是否与条件相符时,会调用条件的#===方法,并将 case 的值作为参数传入,即:

num = 1

case num
when 1
  puts "is 1"
else
  puts "is not 1"
end

这段代码实际上是调用

1.===(num)

来判断值是否符合条件的

因此我们可以直接将带有一个参数的 lambda 作为 case 的条件句使用,这样我们就可以用 case 判断任何东西了。例如:

is_odd = lambda do |number|
    number.odd?
end

# 该示例没有实际用途,
case 1
when is_odd
  puts "is odd"
else
  puts "is even"
end

# => is odd

另外,其实使用 Proc 也是可以的。


写在最后

文章内容错误的地方,欢迎及时指出。

最後までご覧いただいてありがとうございます


Ruby 小技巧系列

点赞

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注