位置:首页 > Ruby > Ruby中Block代码块入门教程与用法详解

Ruby中Block代码块入门教程与用法详解

时间:2026-08-18  |  作者:云端旅人  |  阅读:0

在Ruby的世界里,代码块(block)是一个绕不开的核心概念。 只要写稍微深入一点的Ruby代码,几乎都会和它打交道。

简单说,代码块就是一段被{}或者do...end包裹起来的代码。它不能单独存在,必须紧跟在某个方法调用后面,由方法内部的yield来触发执行。

看个最直接的例子:

Ruby中的block代码块学习教程

[1,2,3,4,5].each { |i| puts i }

[1,2,3,4,5].each do |i| 
  puts i
end

上面两种写法本质一样,只是风格不同。一个用了花括号,一个用了do...end

竖线之间的i就是块变量。它相当于给block传进来的参数。yield每次调用时会把数据塞进来,block拿到后就能执行对应操作。

掌握代码块的编写

最常见的场景,就是遍历数组并对每个元素做操作。

比如说,你想把数组里的每个数字都平方:

array = [1, 2, 3, 4]

array.collect! do |n|
  n ** 2
end

puts array.inspect

# => [1, 4, 9, 16]

collect!是Ruby内置的方法。它把block传进去,每次迭代时把当前元素n交给block处理。

block处理完成后,结果会写回原数组。所以最终数组内容变成了平方后的结果。

自己实现一个类似的迭代器

如果你想自己实现一个类似的迭代器,也很简单:

class Array
  def iterate!
    self.each_with_index do |n, i|
      self[i] = yield(n)
    end
  end
end

array = [1, 2, 3, 4]

array.iterate! do |n|
  n ** 2
end

puts array.inspect

# => [1, 4, 9, 16]

这里的关键是,我们在iterate!方法里没有直接引用block的名字,而是直接用yield来调用它。

  • yield(n)执行时,n会传给block中的参数|n|
  • block执行完最后一行表达式n ** 2
  • 这个结果会自动返回给yield
  • 然后再赋值回数组对应的位置

整个过程清晰、自然。这也是Ruby“块”风格最迷人的地方:灵活又简洁

{}do...end的优先级差异

你可能会觉得,花括号和do...end只是写法不同。其实它们的优先级有区别。

花括号绑定的block优先级更高。 这个差异在执行链式调用时很容易出问题。

来看一个典型场景:

1.upto 3 do |x|
  puts x
end

上面这段没有问题。do...end被绑定到upto方法,3作为参数传给了upto

但同样的逻辑,如果换成花括号,就会报错:

1.upto 3 { |x| puts x }   # 编译错误

原因在于,解释器会把3 { |x| puts x }当成一个整体。

也就是说,它会先理解成:block是跟在3后面的。然后再把3返回的结果作为upto的参数。

显然,3并没有这样一个方法,所以编译就挂了。解决方案很简单:给参数加上括号,明确优先级。

1.upto(3) { |x| puts x }   # 正确

如何避免这类问题

这个小坑其实也是Ruby设计上的一种权衡:

  • 花括号常用于“数据操作”场景,比如mapselect
  • do...end常用于“流程控制”场景,比如循环、文件操作

但归根结底,养成给方法参数加括号的习惯,就能避免绝大多数歧义。

总结

代码块是Ruby的基石之一。从each到自定义迭代器,从简单遍历到高阶函数,它几乎无处不在。

理解它的本质,你写起Ruby代码来会顺手得多。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多