💎 Ruby 闭包
介绍 Ruby 中闭包的实现及其使用方式
由于 Ruby 自身的语法特性,允许方法可以不带括号直接调用,这使得无法在方法内部返回方法。再加上 Ruby 方法内无法访问方法外的变量,导致 Ruby 中的方法不是一等公民,因此无法直接使用方法来实现闭包。
在 Ruby 中,一等公民是 Proc
对象,因此要实现闭包,需使用 Ruby 的 Proc
或 lambda
来实现。
示例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def test_by_Proc(x)
return Proc.new {|y| x + y}
end
def test_by_lambda(x)
return ->(y) {x + y}
end
def test_by_method1(x)
def closure(y)
y
end
return method(:closure)
end
# 下面是错误的
def test_by_method2(x)
def closure(y)
x + y # 内部 def 不能访问外部 def 的局部变量 x
end
return method(:closure)
end
调用闭包
注意,返回闭包后(即 Proc
对象),通过 call
方法或其它同义词方法进行调用执行。例如下面的调用是等价的:
1
2
3
4
puts test_by_Proc(3).call(4)
puts test_by_Proc(3)[4]
puts test_by_Proc(3).(4)
puts test_by_Proc(3).yield(4)
变量作用域
最后需要注意的是 Ruby 中的变量作用域问题。Ruby 采用的是词法作用域,它定义于何处,将见到何处的变量,这与其调用位置无关。
1
2
3
4
5
6
7
8
9
10
11
def func1(pr)
a = "hello"
puts a
pr.call
end
a = "world"
pr = Proc.new {puts a}
a = "WORLD"
pr.call
func1(pr)
输出结果
1
2
3
WORLD
hello
WORLD
总结
在 Ruby 中实现闭包的关键是利用 Proc
和 lambda
,而非直接通过方法。同时,需要理解 Ruby 的词法作用域,以便更好地控制变量的可见性和访问。
本文由作者按照
CC BY 4.0
进行授权