为啥`return a or b`是Ruby中的空值表达式错误?

Posted

技术标签:

【中文标题】为啥`return a or b`是Ruby中的空值表达式错误?【英文标题】:Why is `return a or b` a void value expression error in Ruby?为什么`return a or b`是Ruby中的空值表达式错误? 【发布时间】:2016-04-28 08:57:01 【问题描述】:

这很好:

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 是什么意思?

【问题讨论】:

这不是重复的。我已经删除了对|| 运算符的所有引用,问题仍然存在。请重新打开。 @MsYvette 对不起,我应该考虑到这一点。但是,我希望它仍然可以表明这个被标记为重复的问题没有回答我的问题。 @muistooshort 为什么将其标记为重复?我看到了那个问题,它没有回答我的问题,但sawa 的回答回答了。 我认为这是另一个优先问题(确实如此),但也许我太苛刻了,所以我会重新打开。 【参考方案1】:

return a or b 被解释为(return a) or b,因此return a 的值是计算(return a) or b 的值所必需的,但由于return 永远不会留下一个值(因为它从那个位置逃逸了) ),它的设计目的不是在原始位置返回有效值。因此整个表达式留下了(some_void_value) or b,并被卡住了。就是这个意思。

【讨论】:

【参考方案2】:

在我问的“Does `return` have precedence to certain operators in Ruby?”中,Stefan 在评论中解释说orand 实际上是控制流操作符,不应用作布尔运算符(分别为||&&)。

他还引用了“Using “and” and “or” in Ruby”:

andor 起源于 Perl(就像 Ruby 一样)。在 Perl 中,它们主要用于修改控制流,类似于 ifunless 语句修饰符。 (...)

他们提供了以下示例:

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 explained 中的 a or b 表达式为:

return a or b

优先级低于return a,后者在执行时会转义当前上下文并且不提供任何值(void value)。这会触发错误(repl.it execution):

(repl):1: 空值表达式

puts return a or b
              ^~

由于Stefan comments,这个答案成为可能。

【讨论】:

【参考方案3】:

仅仅因为or|| 有lower precedence,这意味着return a 将在or b 之前执行,因此or b 无法访问

【讨论】:

以上是关于为啥`return a or b`是Ruby中的空值表达式错误?的主要内容,如果未能解决你的问题,请参考以下文章

Ruby SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B:

在 PHP 中,为啥“or die()”有效,而“or return”无效?

EXCEL这列中的空单元格为啥选“空值”定位不了?

为啥 Ruby 中的 `a = a` `nil`?

为啥 PHP 的空合并运算符 (??) 不能处理具有不同可见性的类常量?

Lua - 执行return和or时出错