Ruby中的Proc 和 Lambda

本文介绍了Ruby编程中Each循环的使用,重点讨论了Proc和Lambda的概念、定义、调用方式以及两者之间的区别。Proc和Lambda作为可赋值的‘函数’,可以通过call、[]或.()进行调用。主要的区别在于参数匹配和return行为。Proc和Lambda的使用能够利用闭包特性,提供更灵活的编程方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Each循环

For循环在Ruby中不常见,因为当我们需要循环时,我们会根据惯用法这样写:

1.upto(5).each { |e| 
  puts e 
}

以上代码等价于:

print = lambda { |e| puts e }
1.upto(5).each(&print)

1.upto(5) 的返回值为 [1,2,3,4,5], 是一个数组实例(Array Instance)

each 是数组的实例方法(Instance Method),我们可以像调用其它普通方法(Method)一样来调用each

我们定义了 print 这个 Lambda,并把它用为调用 each 时的最后一个特殊“(Block)”参数

我们使用 (Ampersand)将print类型Lambda转为(Block)

 

块(Block)

在Ruby中每一次调用方法都可以传入一个块参数

块参数可以没有但最多只能有1个。

传入块参数的方法有两种:

  1. 直接以 do..end{...} 的方式直接写在方法后面
  2. 写为最后一个参数并且类型为Block

在第二种方法里,使用 Lambda转换为是关键

1.upto(5).each(print) 是错误的写法,Ruby解释器会以为你传给了each一个“真正”的参数,而each方法不接受“真正”的参数。

如果忘了写 &,那么你会得到

"Error: #<ArgumentError: wrong number of arguments (1 for 0)>"

 

Proc 和 Lambda 的定义与调用

Proc Lambda 非常类似, 并且在Ruby中都为Proc类型(Lambda不是一个类名)。你可以把它们理解成可以赋值给变量的“函数”。

定义Proc需使用new关键词后边接一个block

is_one = Proc.new { |x| x == 1 }

当然你也可以写成 Proc.new(&another_proc) ,但是这样写只是绕远路并没有好处

定义Lambda有两种写法:

is_two = lambda { |x| x == 2 }
is_three = -> (x) { x == 3 } # Rails中常见

你可以把一个普通的方法转换为Lambda。我们首先需要获得方法对象然后使用to_proc

def method_is_four(n)
  n == 4
end

is_four = self.method(:method_is_four).to_proc

在Ruby中调用ProcLambda的方法有三种:

  1. call
  2. []
  3. .()
is_one.call(1) # true
is_two[1]      # false
is_three.(1)   # false

使用case时,接在when后面的ProcLambda会被自动调用

case 2
when is_one
  puts "one"
when is_two
  puts "two"
else
  puts "unknown"
end
# 运行结果:two

Proc 与 Lambda 的区别

ProcLambda 最大的区别有两个

  1. 调用Lambda时传入的参数数量需与定义时一致。调用Proc时缺少的参数将被默认为nil
  2. Lambdareturn退出Lambda本身。在Proc中return退出包裹Proc的外层方法
is_one.call() # proc: false
is_two.call() # lambda: Error: #<ArgumentError: wrong number of arguments (0 for 1)>
def method1
  lambda { 
    return 'lambda'
  }.call

  return 'method'
end
# 运行结果:method

def method2
  Proc.new { 
    return 'proc'
  }.call

  return 'method' #这句不会被执行因为上面的proc抢先return了
end
# 运行结果:proc

Proc 与 Lambda 的好处

使用Proc Lambda 的好处在于可以利用它们被定义时的作用域,也就是闭包闭包这个主题会在以后的文章中与大家分享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值