Ruby 中的 block、proc、lambda

作者: raosheng1993
发布时间:2015-07-13 11:15:31



原文来自于:
http://railstalk.com/?p=28

Ruby Block  先举两个例子,each使用block [1,2,3,4,5].each do | number |      puts number end   [1,2,3,4,5].each { |number |     puts number }  可以看出我们使用do...end 或者 {...} 来调用block。 { | number | puts number }  这个就是Ruby的block  Ruby中的block其实就相当于Javascript中的异步函数,存储了调用函数,直到被调用。  其中 | number | 只是异步函数的参数。  Ruby 的 block 传递给函数时,使用 █ 这样的形式,在参数前加 & ,则参数被识别为 block。 调用 block 时,需要时 call 。 block.call(...)  同时,Ruby block 可以在函数中不声明参数,而只使用yield。如: def call_block_without_argument      yield         end  call_block_without_argument { puts "Hello Block" }  Ruby Proc  Proc 对象是一段捆绑在一起的代码,被设置为局部变量,可以在上下文中被调用。例: multiply = Proc.new { | a, b | puts a * b } multiply.call( 3, 4 )  # print out 12   同时,可以绑定一系列变量到 Proc ,这样在调用中可以使用这些变量。例: def multiply_with( factor )      return Proc.new { | number | number * factor } end  multiply_with 函数将返回一个 Proc 对象,同时包含一个参数。 multiply_with_10 = multiply_with( 10 ) # call multiply_with_10 with a number multiply_with_10.call( 12 ) # return 120 # or you can call in another way multiply_with_10[12] # return 120  可以看到 factor 参数在函数中在创建是赋给 Proc,然后就会永久的存在 Proc 中,这样就可以随时调用了。  另外,Proc 可以象 Block 一样传递给函数。当然有些不一样的地方。 def print_with_postfix( postfix )      return Proc.new { |printing_content| puts "#{printing_content} #{postfix}" }  end 然后可以把返回的 Proc 对象象其他函数参数值一样传递给 print_with_postfix 函数。  print_with_postfix_bye = print_with_postfix( "bye" ) print_with_postfix_end = print_with_postfix( "end" )        def print_content( content, print_style )     print_style.call( content ) end   print_content( "Hello world", print_with_postfix_bye ) # print out Hello world bye print_content( "Hello world", print_with_postfix_end ) # print out Hello world end  Block 和 Proc 间的转换使用 & 。 在函数调用时我们使用 &variable 类似的格式来传递参数值,这就把 Block 转换成了 Proc, 这样就可以在函数中使用 call 来调用。  同时也可以使用 & 将 Proc 对象转换成 Block。  multiply_with_10 = Proc.new { | number | puts number * 10 } [1,2,3,4].each( μltiply_with_10 )   # 10 # 20 # 30 # 40  因为在 each 函数中接收 block 作为参数值。而这里我们使用了一个 Proc,就需要加上 & 来把 Proc 转换为 Block。  Lambda lambda 是创建 Proc 的函数 multiply_lambda_proc = lambda { | x, y | x * y } # and we can call as a normal Proc multiply_lambda_proc.call( 3, 4 ) # return 12  但 lambda 和 proc 有两个不同点: lambda 对参数做检查,而 proc 不检查。例:  multiply_lambda_proc = lambda { | x, y | x * y } multiply_proc = Proc.new { | x, y | x * y }  multiply_lambda_proc.call( 3, 4, 5 ) # ArgumentError: wrong number of arguments (3 for 2) multiply_proc( 3, 4, 5 ) # return 12 as normal  # This last command's error shows that Proc auto assigns missing argument with nil multiply_proc( 3 )  # TypeError: nil can't be coerced into Fixnum  lambda 返回到调用者的函数,而 proc 返回到内部的函数。  def return_from_proc       ruby_proc = Proc.new { return "return from a Proc" }       ruby_proc.call       return "The function will NOT reach here because a Proc containing a return statement has been called" end  def return_from_lambda       ruby_lambda = lambda { return "return from lambda" }       ruby_lambda.call       return "The function will reach here" end  puts return_from_proc # display return from proc puts return_from_lambda # display The function will reach here  在这个例子中,可以看到 proc 包含的一个 return 语句被调用,将会返回整个函数,而lambda 

版权声明:本文为博主原创文章,未经博主允许不得转载。

标签: Lambda Ruby
来源:http://blog.csdn.net/raosheng1993/article/details/45396609

推荐: