在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
1、什么是代码块 在Ruby中,{}或do...end之间的代码是一个代码块。代码块只能出现在一个方法的后边,它紧接在方法最后一个参数的同一行上,由yield关键字调用。例如: [1,2,3,4,5].each { |i| puts i }
[1,2,3,4,5].each do |i|
puts i
end
块变量:以yield关键字调用block也可以传递参数,block中竖线(|)之间给出的参数名用于接收来自yield的参数。 竖线之间(如上例中的 | i |)的变量被称作块变量,作用和一个正常方法的参数一样
2、{}和do...end优先级不同 在传递一个block时,使用{}传递的block比使用do…end的优先级要高; 为了避免引起歧义,最好使用()将参数括起来。例如: 1.upto 3 do |x|
puts x
end
是正确的,但是 1.upto 3 {|x| puts x} 编译不通过,应该写成 1.upto(3) {|x| puts x} 原因: 1.upto 3 do…end 中block会传递到upto方法里面,3会作为一个参数传递给upto 1.upto 3 {|x| puts x} 一句会把3当做函数名,将block传递到这个函数,其返回值作为upto方法的参数,所以编译不过,需加()。
3、代码块转化为对象的方法 代码块并不是对象,但可以通过以下三种方法转化为Proc类的对象: (1)将一个代码块传递给最后一个参数以 & 开始的方法。例: def meth1(p1, p2, &block) puts block.inspect puts block.call end meth1(1, 2) { "This is a block" } (2)使用Proc.new方法,代码块作为参数: block = Proc.new { "a block" } (3)调用Kernel.lambda方法: block = lambda { "a block" } 前两种方法是等价的,会检查参数的数量,但Proc.new 创建的对象不会; 用 lambda 和 Proc.new 生成的 Proc 对象之间也是有差别的。这个差别与 return 关键字相关。lambda 中的 return 从 lambda 返回。而 Proc.new 中的 return 从外围方法返回。 # 执行后"Never come here"不会被输出,执行p.call相当于在test_proc方法内执行了return语句。
def test_proc
p = Proc.new { return 1 } # test_proc方法返回
p.call
puts "Never come here" # 永远不会执行到
end
# 使用lambda生成的Proc对象执行call方法调用时,return表示从lambda包围得块内返回。
def test_lambda
p = lambda { return 1 }
result = p.call
puts "The value is: #{result}"
end
Note:在一个代码块中执行next语句会导致代码块返回。返回值就是next语句后带的参数。如果next后没有参数,那么返回值为nil。 def meth2
result = yield
p "The block result is #{result}"
end
puts meth2 { next 9 }
pr = Proc.new { next 100 }
puts pr.call
pr = lambda { next }
puts pr.call
执行结果为:
The block result is 9
100
nil
4、yield关键字调用代码块 在方法中可以使用 yield 来执行代码块的内容,就好像传入的代码块是这个方法的一部分一样。每当碰到一个 yield,代码块的内容就会被执行一次,代码块执行结束后,程序会回到 yield 的那一行继续向下执行。 使用 yield 可以向代码块传递参数,也可以从代码块取回返回值,返回值就是代码块中最后一个表达式的值。 def fibonacii(max) f1, f2 = 1, 1 while f1 <= max yield f1 f1, f2 = f2, f1+f2 end end fibonacii(1000) { |f| print f, " " } 执行结果为: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 (1)在这个例子中,yield 接收一个参数f1,这个参数将会在执行的时候传递给指定的代码块。在代码块中,接收的参数使用两个竖线括起来放在代码块的头部。 (2)另外,在使用 yield 关键字调用代码块时,如果传入的参数个数少于代码块中定义的参数个数,那么没有传递的参数会自动转为nil。反之,则最后一个参数为一个数组,该数组包含了剩余的传递参数; |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论