Ruby do/end vs 大括号

Posted

技术标签:

【中文标题】Ruby do/end vs 大括号【英文标题】:Ruby do/end vs braces 【发布时间】:2011-07-27 16:16:56 【问题描述】:

为什么这个 map 表达式会根据我使用大括号还是 do/end 产生不同的结果?

a = [1,2,3,4,5]


p a.map  |n|
    n*2
  
#=> [2,4,6,8,10]


p a.map do |n|
    n*2
end  
#=> [1,2,3,4,5]

【问题讨论】:

直到今天仍然有效 这能回答你的问题吗? Using do block vs braces 【参考方案1】:

那是因为第二行被解释为:

p(a.map) do ... end

代替:

p(a.map do ... end)

在这种情况下,语法不明确,do 的绑定似乎不如 强。

【讨论】:

@Grandpa 这不是特别关于“p”。这是关于方法的参数/块和之间的强度/优先级,做结束 如何才能将do...end 与多行块一起使用,以便map 将其作为参数?大括号 - 根据您的建议 - 不会这样做,Ruby 会抛出错误,unexpected keyword_do_block 甚至整个块都是一行。 @karatedog:你可能需要在这里使用一个中间变量,因为解析器不支持你想要的。 @DarkDust 谢谢,但当 Enumerator 无限时我不能使用中间变量,因为我必须事先知道我应该在该中间变量中生成多少项目。 我不明白你的意思,当然你可以foo = a.map do ... end ; p(foo)。这是完全相同的语义,因为map 总是需要先聚合一个数组才能传递。然后将该数组存储在变量中或作为参数传递给另一个方法都没有区别,无论如何都需要先创建数组。【参考方案2】:

这与 字符和do 关键字的关联性不同有关。

在第一种情况下,块被解释为map 函数的块参数。 map 函数的结果是p 函数的参数。

在第二种情况下,块被解释为p 函数的块参数,而a.map 被解释为p 函数的第一个参数。由于a.map 的计算结果为a,因此将打印原始数组。在这种情况下,该块实际上被忽略了。

【讨论】:

【参考方案3】:

使用do/end 语法,您将块作为第二个参数传递给p,而不是传递给地图。您会得到相同的结果:

p a.map

p 忽略该块,因为它不会在 inspect 上产生任何内容。

【讨论】:

以上是关于Ruby do/end vs 大括号的主要内容,如果未能解决你的问题,请参考以下文章

属性值绑定:方括号 vs 大括号

VS Code 突然停止右括号、方括号和大括号

每次输入大括号时 VS 2019 都会发出声音

VS2015大括号高亮显示的设置方法

VS C++学习--设置代码行号背景颜色大括号垂直线对齐

在大括号之间搜索和替换文本(VS代码)