【发布时间】:2014-07-04 19:48:01
【问题描述】:
我最近发现了一个我不完全理解的 Ruby 问题。那么,有人可以向我解释为什么 Ruby 中的以下 2 个语句不一样-
puts "foo" and return if true
VS
if true
puts "foo"
return
end
【问题讨论】:
我最近发现了一个我不完全理解的 Ruby 问题。那么,有人可以向我解释为什么 Ruby 中的以下 2 个语句不一样-
puts "foo" and return if true
VS
if true
puts "foo"
return
end
【问题讨论】:
要理解您问题中的单行符,您需要记住 Ruby 运算符及其优先级。或者,更准确地说,Ruby 语法。您需要以与 Ruby 解释器完全相同的方式查看语句。它必须成为你的第二天性。现在让我们看看你的单线
puts "foo" and return if true
让我们先把不相关的问题分开。关键字 return 仅适用于方法或 lambda,并不是您问题的真正主题。此外,尾随if true 始终有效,因此似乎没有必要。为了一般性地讨论您的问题,让我们定义方法 #bar 和变量 baz
def bar
puts "bar"
end
baz = true
让我们谈谈修改后的单线
puts "foo" and bar if baz
如果您已经记住了 Ruby 语法,您将能够完全按照 Ruby 看到的方式为该行加上括号:
( puts( "foo" ) and ( bar ) ) if ( baz )
尾随if 的行为类似于优先级很低的运算符。仅当 baz 为 true 时,才会执行从开头到 if 的整行,它确实如此。因此,
puts "foo" and bar
被执行。括号内如下:
puts( "foo" ) and ( bar )
可以看到puts "foo"先被执行,在屏幕上打印foo并返回nil。由于nil 是错误的,运算符and 只是返回它,而其右侧的bar 永远不会被执行。
至于
if baz
puts "foo"
bar
end
相当于:
( puts( "foo" ); bar ) if ( baz )
可以看出区别:puts "foo"和bar不是由and连接的,而是独立的逻辑行。第一行的返回值被丢弃,不影响第二行的执行。
最后,让我们看看将and 替换为&& 会发生什么。因为&&操作符的优先级比and高很多,所以oneliner
puts "foo" && bar
变成
puts( "foo" && bar )
换句话说,"foo" && bar 的值将首先被计算,然后作为参数传递给#puts 方法。因为字符串"foo" 被认为是真的,所以执行继续到bar,它在屏幕上打印"bar" 并返回nil。你可以自己试试看的值
"foo" && bar
是nil,作为副作用在屏幕上打印"bar"。
puts( "foo" && bar )
就变成了
puts( nil )
这会导致在屏幕上打印一个空行。
士气是应该学习语法。 Ruby 设计师迈出了一大步,使代码像书一样一目了然。
【讨论】: