Ruby多行块没有结束怎么办?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (42)

我是Ruby的初学者,但是这个代码有什么问题吗?

3.upto(9) {
  print "Hello"
  puts " World"
}
3.upto(9) { |n|
  print "Hello "
  puts n
}

它工作得很好,但我看到的大多数代码示例都使用了

3.upto(9) do |n|
  print "Hello "
  puts n
end

仅对单个语句使用大括号只是惯例吗?来自C/C#的第一个对我来说似乎更自然。

提问于
用户回答回答于

这两种语法之间存在细微差别。{ }优先级于do ... end。因此,下面将通过bar一个块和方法foo

foo bar do ... end

而以下内容将通过一个块bar,并将结果传递给foo

foo bar { ... }

所以你的例子将采取相同的行动。但是,如果放弃括号:

> 3.upto 9 { 
  puts "Hi" 
}
SyntaxError: compile error
(irb):82: syntax error, unexpected '{', expecting $end
3.upto 9 { 
          ^
    from (irb):82
    from :0

> 3.upto 9 do 
    puts "Hi" 
  end
Hi
Hi
Hi
Hi
Hi
Hi
Hi
=> 3

所以,{ }如果你在Ruby中省略了括号,这很常见; 出于这个原因,并且因为Ruby条件和其他控制结构都end用作分隔符,所以人们通常do ... end用于语句结尾处的多行代码块。

但是,{ }在经常使用的地方do ... end会比较麻烦,例如,如果将几个方法链接在一起,需要使用块。这可以让你编写简短的一行小块,可以用作方法链的一部分。

> [1,2,3].sort{|x,y| y<=>x}.map{|x| x+1}
=> [4, 3, 2]

下面是一个例子来说明这种差异:

def foo arg
  if block_given?
    puts "Block given to foo"
    yield arg
  else
    puts "No block given to foo"
    arg
  end
end


def bar
  if block_given?
    puts "Block given to bar"
    yield "Yielded from bar"
  else
    puts "No block given to bar"
  end
  "Returned from bar"
end

irb(main):077:0> foo bar { |arg| puts arg }
Block given to bar
Yielded from bar
No block given to foo
=> "Returned from bar"
irb(main):078:0> foo bar do |arg| puts arg end
No block given to bar
Block given to foo
Returned from bar
=> nil
用户回答回答于

扫码关注云+社区