2.12Ruby语言的两种闭包(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/back/ruby/4558.html

发表评论

登录后才能评论