• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell
您的位置:首页 > 脚本语言 >ruby > Ruby中的block、proc、lambda区别总结

Ruby中的block、proc、lambda区别总结

作者:junjie 字体:[增加 减小] 来源:互联网

junjie 通过本文主要向大家介绍了ruby proc,ruby block,ruby,ruby rose,ruby什么意思等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

在规则引擎中,Ruby 的闭包使用特别频繁,而且有 block,Proc和 lambda 等后几种形式的用法,很让人困惑。为了深入理解代码,再次认真学习了一下 Ruby 的闭包,特别是 block,proc 和 lambda 几种用法的异同,这次的周记就和大家分享一下心得。

闭包是 Ruby 相对其它语言特别优势之一,很多语言有闭包,但是唯有 Ruby 把闭包的优势发挥得淋漓尽致。Ruby 的哲学之一:同一个问题现实中有多种解决方法,所以 Ruby 中也有多种解法,所以闭包的使用也有多种方法。

先看一个代码的例子:

Example 1:
def foo1
  yield
end

def foo2(&b)
  b.call if b
end

foo1 { puts "foo1 in block" }
foo2 { puts "foo2 in block" }
proc = Proc.new { puts "foo in proc" }
foo1(&proc)
foo2(&proc)
lambda_proc = lambda { puts "foo in lambda" }
foo1(&lambda_proc)
foo2(&lambda_proc)
</div>

输出:
》foo1 in block
》foo2 in block
》foo in proc
》foo in proc
》foo in lambda
》foo in lambda
</div>

大家是不是有些困惑,首先是方法 foo1 和 foo2 都能接收闭包,它们这两种写法有什么区别,然后是作为参数的三种闭包 block,proc和 lambda有什么区别。

1. yield 和 block call 的区别

yield 和 block call 两种都能实现运行闭包,从实际运行效果来说,区别不大。其区别主要在于:

1.1 闭包的传递和保存

因为闭包已经传递到参数里,所以可以继续传递或保存起来,例如:

Exampl 2:
 class A
      def foo1(&b)
         @proc = b
      end
      def foo2
          @proc.call if @proc
      end
   end

    a = A.new
    a.foo1 { puts "proc from foo1" }
    a.foo2
</div>

1.2 性能

yield不是方法调用,而是 Ruby 的关键字,yield 要比 block call 比快 1 倍左右。

2. block 和 proc, lambda 的区别

很简单直接,引入 proc 和 lambda 就是为了复用,避免重复定义,例如在 example 1 中,使用 proc 变量存储闭包,避免重复定义两个 block 。

3. proc 和 lambda 的区别

这大概是最让人困惑的地方,从 Example 1 的行为上看,他们的效果是一致的,为什么要用两种不同的表达方式。
 proc = Proc.new { puts "foo in proc" }
   lambda_proc = lambda { puts "foo in lambda" }
</div>

确实,对于简单的情况,比如 Example 1的情况,他们的行为是一致的,但是主要在两个地方有明显差异:

1.1 参数检查

还是例子说话 Example 3:
def foo
      x = 100
      yield x
   end

   proc = Proc.new { |a, b| puts "a is #{a.inspect} b is #{b.inspect}" }
   foo(&proc)


   lambda_proc1 = lambda { |a| puts "a is #{a.inspect}" }
   foo(&lambda_proc1)
   lambda_proc2 = lambda { |a, b| puts "a is #{a.inspect} b is #{b.inspect}" }
   foo(&lambda_proc2)
</div>

输出

   》a is 100 b is nil
   》a is 100
   》ArgumentError: wrong number of arguments (1 for 2)
      …
</div>

可见,proc 不会对参数进行个数匹配检查,而 lambda 会,如果不匹配还会报异常,所以安全起见,建议优先用 lambda。

1.2 返回上层

还是例子说话 Example 4:

 def foo
     f = Proc.new { return "return from foo from inside proc" }
     f.call # control leaves foo here
     return "return from foo"
   end


   def bar
     f = lambda { return "return from lambda" }
     puts f.call # control does not leave bar here
     return "return from bar"
   end


   puts foo
   puts bar
</div>

输出

   》return from foo from inside proc
   》return from lambda
   》return from bar
</div>

可见,proc 中,return 相当于执行了闭包环境里的 return,而 lambda 只是返回call 闭包所在环境。

总结:闭包是 Ruby 的强大特性,它的几种表达方式block,proc 和 lambda有细微差别,要用好它需要对其深入理解。

</div>

您可能想查找下面的文章:

  • Ruby中使用Block、Proc、lambda实现闭包
  • Ruby中的Proc类及Proc的类方法Proc.new的使用解析
  • 详解Ruby中的代码块对象Proc
  • Ruby中proc和lambda的两个区别
  • Ruby中的block、proc、lambda区别总结

相关文章

  • Ruby on Rails网站项目构建简单指南
  • 浅谈Ruby on Rails的国际化
  • Ruby简洁学习笔记(一):字符串、数字、类和对象
  • 使用Ruby来处理文本的教程
  • 比较不错的关于ruby的电子书下载地址集合
  • print不自动换行,puts会自动换行第1/2页
  • Ruby语法笔记
  • ruby 模块
  • rudy 重载方法 详解
  • 编写Ruby代码注释时需要注意的一些问题

文章分类

  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell

最近更新的内容

    • Ruby中require、load、include、extend的区别介绍
    • Ruby on rails安装后去掉DL is deprecated,please use Fiddle警告信息的方法【测试可用】
    • Ruby中关于hash的基本使用方法
    • Ruby中的变量学习总结
    • Ruby On Rails中如何避免N+1问题
    • Ruby 中一些百分号(%)的用法小结
    • 在Ruby中处理文件的输入和输出的教程
    • Ruby类继承、抽象类、类拓展混入、代理类实例
    • Ruby简明教程之循环语句介绍
    • Ruby迭代器的7种技巧分享

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有