【问题标题】:What does a Ruby case expression mean without an expression to inspect?如果没有要检查的表达式,Ruby case 表达式意味着什么?
【发布时间】:2017-03-01 04:40:08
【问题描述】:

以 Ruby 表达式为例:

case
  when 3 then "foo"
  when 4 then "bar"
end

我惊讶地发现这不是语法错误。相反,它的计算结果为 "foo"!

为什么?这里应用的语法和评估规则是什么?

【问题讨论】:

    标签: ruby syntax switch-statement semantics


    【解决方案1】:

    case 表达式的这种形式中,与计算结果为truthy 值的词汇上第一个when 子句相关联的then 子句被计算。

    参见ISO Ruby Language Specification 的§11.5.2.2.4 语义的第 b) 2) 条(粗体强调我的):

    语义

    case 表达式的求值方式如下:

    • a) […]
    • 乙。步骤 c) 中的短语“O is matching”的含义定义如下:
      1. […]
      2. 如果 case-expressioncase-expression-without-expressionO 匹配当且仅当 O 是一个真实的对象。
    • c) 采取以下步骤:
      1. when-clauses 按照它们在程序文本中出现的顺序搜索匹配的when-clause,如下所示:
        • i) 如果 when-argumentoperator-expression-list 存在:
        • I) 对于它的每个 operator-expression,对其求值并测试结果值是否匹配。
        • II) 如果找到匹配值,则不计算其他 operator-expression(如果有)。
        • ii) 如果没有找到匹配值,并且 splatting-argument(参见 11.3.2)存在:
        • I) 根据 11.3.2 中的描述构造一个值列表。对于结果列表的每个元素,按照列表中相同的顺序,测试它是否匹配。
        • II) 如果找到匹配值,则不会评估其他值(如果有)。
        • iii) 当且仅当在其 when-argument 中找到匹配值时,when-clause 被认为是匹配的。后面的 when-clauses,如果有的话,在这种情况下不会被测试。
      2. 如果其中一个 when-clause 匹配,则评估此 then-clausecompound-statement当子句case-expression 的值就是结果值。
      3. 如果没有一个 when-clause 匹配,并且如果存在 else-clause,则评估 compound-statement else 子句case-expression 的值就是结果值。
      4. 否则,case-expression 的值为nil

    RDoc documentation 虽然不那么精确,但也指出 真实性 是选择标准,当条件被省略时;并且词汇顺序决定了检查when 子句的顺序(粗体强调我的):

    case

    case 语句运算符。 Case 语句由一个可选条件(位于case 的参数位置)和零个或多个when 子句组成。 第一个匹配条件的when 子句(或评估为布尔真值,如果条件为空)“获胜”,并执行其代码节。 case 语句的值是成功的when 子句的值,如果没有这样的子句,则为nil

    【讨论】:

    • 您的代码示例不等效。在您的示例中,3 将不匹配,因为 3 === truefalse。安德烈的答案实际上是正确的。
    • 谢谢。我不知道我在想什么!这样更好吗?
    • 顺便说一句:我刚刚注意到文档中的“等效”代码示例也是错误的。嗯。
    • 感谢指正。现在好多了。还要感谢您引用 ISO 标准,因为它是一个非常昂贵的参考 :)
    • 那么,不要告诉任何人我引用的草案! ;-)
    【解决方案2】:

    根据设计,没有匹配值的case 语句的行为类似于if 语句。

    其实和写作一样:

    if 3
      'foo'
    elsif 4
      'bar'
    end
    

    【讨论】:

      猜你喜欢
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 2018-09-30
      • 1970-01-01
      • 2020-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多