为什么`在Ruby中返回a或b`是一个void值表达式错误?
这很好:
def foo a or b end
这也没关系:
def foo return a || b end
这将返回void value expression
:
def foo return a or b end
为什么? 它甚至没有被执行; 它没有通过语法检查。 void value expression
意味着什么?
return a or b
被解释为(return a) or b
,因此return a
的值是计算(return a) or b
的值所必需的,但是因为return
永远不会留下值(因为它从中逃脱位置),它不是为了在原始位置返回有效值而设计的。 因此整个表达式留有(some_void_value) or b
,并且被卡住了。 这就是它的含义。
仅仅因为or
优先级低于||
这意味着return a
将在之前执行or b
, or b
因此无法访问
根据我之前提出的类似问题 , Stefan在评论中解释说or
和and
实际上是控制流操作符 ,不应该用作布尔运算符(分别是||
和&&
)。
他还引用了一篇解释这些控制流操作符背后原因的文章 :
and
/or
在Perl中发起(像许多Ruby一样)。 在Perl中,它们主要用于修改控制流,类似于if
和unless
语句修饰符。 (……)
它们提供以下示例:
and
foo = 42 && foo / 2
这相当于:
foo = (42 && foo) / 2 # => NoMethodError: undefined method `/' for nil:NilClass
目标是为foo
分配一个数字,并将其重新分配给它的一半值。 因此and
运算符在这里很有用,因为它的优先级较低,它修改/ 控制各个表达式的正常流程 :
foo = 42 and foo / 2 # => 21
它也可以在循环中用作反向if
语句:
next if widget = widgets.pop
这相当于:
widget = widgets.pop and next
or
用于将表达式链接在一起
如果第一个表达式失败,请执行第二个表达式,依此类推:
foo = get_foo() or raise "Could not find foo!"
它也可以用作:
反转
unless
语句修饰符:raise "Not ready!" unless ready_to_rock?
这相当于:
ready_to_rock? or raise "Not ready!"
因此, sawa解释了a or b
表达式:
return a or b
优先级低于return a
,执行时,它会转义当前上下文并且不提供任何值( void值 )。 然后这会触发错误( repl.it执行 ):
(repl):1:void值表达式
puts return a or b ^~
由于Stefan评论 (谢谢),这个答案成为可能。