【问题标题】:What's the point of "for x in y" in Ruby?Ruby 中的“for x in y”有什么意义?
【发布时间】:2011-03-21 13:04:43
【问题描述】:

我现在正在学习 Ruby 和 RoR,我遇到了这个:

<% for post in @posts %>

Rails guide。我知道在 Ruby 中执行此操作的惯用方法是:

<% @posts.each do |post| %>

如果有区别,那是什么?如果没有区别,那么 Rails 人员推动正确的 Ruby 习语不是更好吗(而不是这个,这对我来说看起来更像 Python)?

编辑:我刚刚发现了两个相互矛盾的解释:Tutorials Point 说它们是相同的,除了“for 循环不会为局部变量创建新范围”,而CS.Auckland.ac.NZ 表示 for 只是等效 .each 的语法糖。

Edit2: 有问题的for ... in 是由script/generate scaffoldapp/views/posts 中生成的index.html.erb。我做了一个快速检查,现在生成了.each 语法。我猜该指南的一部分是在 Rails 开发的早期阶段编写的,当时脚手架生成了for ... in

Edit3:我现在可以确认在 Rails 2.2.2 中使用了 for x in y,但到了 2.3.8,它正在使用 y.each do |x|。让你知道。

【问题讨论】:

    标签: ruby-on-rails ruby idioms


    【解决方案1】:

    关于for x in y 的另一件事是,您可以执行for i in 1..5,它将像标准for 循环一样工作,从i = 1 开始,一直到i = 5

    这样做的方便之处在于,您可以使用3..8x..y 之类的范围,您不会从零开始卡住,而使用n.times 方法会卡住。

    【讨论】:

    • 不会 1.upto(5).each {|x| #something} 解决这个问题?
    • @jeba 是的。我对红宝石比较陌生,所以我以前没见过。所以谢谢!我每天都能学到新东西!
    • 你也可以(1..5).each
    【解决方案2】:

    如果您尝试进行 ruby​​ 分析并且您的 ruby​​-prof 版本没有 method elimination,您可能想要使用 for x in y

    【讨论】:

      【解决方案3】:

      tutorialpoint 页面是正确的,for 等同于each,除了范围不同。这是一个演示:

      arr = [1,2,3]
      arr.each do |x|
        last = x
      end
      last # NameError
      

      对比

      arr = [1,2,3]
      for x in arr
        last = x
      end
      last #=> 3
      

      如果您想使用each 使其工作,您需要在循环之前执行last = nil。正如链接所指出的,这是因为块会启动一个新的范围,而 for 不会。

      但是请注意,这很少会产生实际影响,甚至很少有人意识到这一点。

      当人们在 ruby​​ 中使用 for 时,最常见的原因是他们习惯于使用其他语言 - 而不是因为 foreach 之间的任何差异。

      【讨论】:

      • 谢谢!正是我想要的。不过,这让我回到了最初的观点,这就是为什么 Rails 团队(或至少编写入门指南的人)会使用 for ... in 语法的原因?
      • 有很多人在没有先学习 ruby​​ 的情况下学习 Rails。我想该指南的编写风格旨在让来自其他语言的人看起来很熟悉。
      • 两者之间的相关差异仅从该示例中并不明显:a=[]; for x in [1,2,3,4]; a &lt;&lt; proc {x} end; map(&amp;:call) 给出 [4,4,4,4] 而与 each 等效的将给出 [1,2,3,4],因为 each 引入了一个新的x 每次迭代都绑定。
      • 性能方面,我想for x in arr 会快一点,但这并不重要
      • 这些结构之间存在差异,但我怀疑这是否是引入它们的真正原因。
      【解决方案4】:

      有一天我正在为我正在开发的网站开发生成 PDF 报告的功能。

      我使用的插件有很多限制。这些限制迫使我提出了非常必要和程序化的解决方案。我使用 whilefor 之类的结构只是为了强调这种编程风格。

      事实上,这是我在 ruby​​ 中使用这些关键字的唯一情况。

      【讨论】:

        【解决方案5】:

        问题是第一个示例 (for post in @posts) 看起来更“程序化”,而第二个示例 (@posts.each do |post|) 看起来更“实用”。不幸的是,阅读代码的程序化方式仍然被认为更流行、更清晰、更不“怪诞”。这就是为什么许多人更喜欢它而不是迭代容器的“本机”方式。

        如果它看起来像pythonic(我不确定它是否属实),那么它可能会被认为更好,因为它提高了来自其他平台的开发人员对 Rails 的可访问性。

        就个人而言,我希望推动 ruby​​ 和“功能”的方式。但以上原因表明,这两种方法都可以。

        【讨论】:

        • 我说它看起来像 Python,因为 for ... in 是 Python 中迭代的标准方式。
        • @skill,以及它是在其他语言中迭代的标准方式(例如,过时的 Perl 语法)。它也是迭代任何集合的自然(在某种意义上说是人类如何看待它)。
        • 是的,我明白你的意思。我不一定说他们在复制 Python,只是说它看起来更像 Python。
        猜你喜欢
        • 2021-08-07
        • 2021-03-20
        • 2013-11-29
        • 1970-01-01
        • 2018-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-07
        相关资源
        最近更新 更多