1.11Ruby语言的两种闭包(Closure):Proc和Lambda

形成闭包的两个特征:

  • 块需要调用外围方法的参数或局部变量
  • 外围方法有了返回以后,外围方法的参数或局部变量没有立即被销毁,依然存在于内存中,直至块执行完毕

首先回顾一下:代码块可以使用在其外定义的方法参数和方法局部变量。比如

def multiply(data, n)
  data.collect { |x| x*n }
end

puts multiply([1,2,3], 2)    #2,4,6

一旦multiply方法有了返回以后,n方法参数将会被销毁,所以,此时还没有形成闭包。那如何形成闭包呢?

可以把代码块变成一个proc或一个lambda,让multiplier方法返回后仍可以访问n,这样便形成了闭包。

def multiplier(n)
  lambda { |data| data.collect { |x| x*n } }
end
doubler = multiplier(2)        #返回一个lambda对象
puts doubler.call([1,2,3])     #2,4,6

代码块是Ruby的一种句法结构,它们不是对象,也不能像对象一样操作,不过,可以创建对象来表示一个代码块。根据对象的创建方式,它被称作一个proc或一个lambda。proc的行为与代码块类似,而lambda的行为则与方法类似,不过它们都是Proc的实例。

Proc方式

#隐性传递Proc对象
def sequence(n,m,c,&b)
  i = 0
  while(i < n)
    b.call(i*m + c)
    i += 1
  end
end

sequence(5,2,2) { |x| puts x }

#显性传递Proc对象
def sequence(n,m,c,b)
  i = 0
  while(i < n)
    b.call(i*m + c)
    i += 1
  end
end

p = Proc.new { |x| puts x }
sequence(5,2,2,p)

Lambda方式

succ = lambda { |x| x+1 }

Lambda字面量方式

succ = ->(x) { x+1 }

原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/ruby/rubylang/4558.html

(0)
上一篇 2020年7月10日 02:45
下一篇 2020年7月12日 18:10

相关推荐

  • 1.4Ruby语言的常见类型(Type)和值(Value)

    虽然Ruby一切面向对象,但是在运行的时候还是会区分值类型和引用类型,比如nil、true、flase、integer均是作为立即值(immediate values)来处理的,类似与C#的值类型,Java的原始类型。 1.NilClass(空) nil对象代表空值。 2.TrueClass(真)和FalseClass…

    Ruby语言教程 2020年7月4日
    01.2K0
  • 2.2Ruby语言的类(Class)、继承(Inheritance)、对象(Object)

    类声明 类 总是以关键字 class 开始,后跟类的名称。 继承 Ruby语言支持单继承,就是说1个子类只可以继承1个父类,可以用mix-in的方式引入模块从而支持“多继承”的效果。 Class是Module的子类,Module是Object的子类,Object是BaseObject的子类,Base…

    Ruby语言教程 2020年8月2日
    06830
  • 1.10Ruby语言的迭代器(Iterator)

    迭代器是一种特殊的带块的方法。 迭代器(iterator)是Ruby最为重要的特性之一,又称为 迭代器方法,虽然while、until和for循环是Ruby语言的核心部分之一,但是通常情况下我们更倾向于使用 迭代器 来编写循环。 从迭代器的英文拼写可以知道,迭代器表示的是循环(iterate)的容器(-or),所以迭代…

    Ruby语言教程 2020年7月10日
    01.0K0

发表回复

登录后才能评论