【问题标题】:Difference between do..end and {} while using block [duplicate]使用块时do..end和{}之间的区别[重复]
【发布时间】:2021-09-22 19:58:59
【问题描述】:

我不知道使用 'do..end' 和 '{}' 有什么区别。

当我在下面使用“do..end”时,它给了我错误 :368:在“每个”中:没有给出块(LocalJumpError)

p [50, 17, 1, 22].inject do |acc, el|
    if el < acc
        el
    else
        acc
    end
end

但是,当我在下面使用“{}”时,它会打印最小值“1”。

p [50, 17, 1, 22].inject { |acc, el|
    if el < acc
        el
    else
        acc
    end
}

是不是因为'优先级'的不同?

【问题讨论】:

标签: ruby


【解决方案1】:

问题纯粹是在使用p 并且,就像你说的,优先顺序 - 因为你依靠 ruby​​ 来定义基于空格的优先级,而不是声明它明确用括号。

ruby 解释器是这样读取的:

p([50, 17, 1, 22].inject) do
  # ...
end

p([50, 17, 1, 22].inject { ... })

...换句话说,当使用do ... end 语法时,块被传递给p 方法,而不是inject 方法!

因此,如果您希望同时保留 do ... end 块语法并打印结果,则必须添加括号,例如:

p([50, 17, 1, 22].inject do |acc, el|
    if el < acc
        el
    else
        acc
    end
end)

或者,分配一个临时变量,例如:

x = [50, 17, 1, 22].inject do |acc, el|
    if el < acc
        el
    else
        acc
    end
end

p x

【讨论】:

  • 作为补充,在解析块时,do...end{} 之间还有另一个显着区别。 [1, 2, 3].inject 0 { |a, b| a + b } 不能工作,因为它需要括号,但 [1, 2, 3].inject 0 do |a, b| a + b end 将按预期工作。
  • 另外作为附录,您可以使用三元语句编写该块:el &lt; acc ? el : acc,甚至将其编写为[el, acc].min。无论哪种方式,它现在都可以整齐地放在一行中,这意味着您在这里不需要do ... end 语法。
  • 学习通常意味着如果您已经了解更多,那么做一些毫无意义的事情,但希望最终会有所启发。 :)
猜你喜欢
  • 2019-07-06
  • 1970-01-01
  • 2016-04-01
  • 2011-07-02
  • 2013-11-02
  • 2016-04-10
  • 2014-08-16
  • 2011-04-08
  • 2012-11-24
相关资源
最近更新 更多