【问题标题】:Fizzbuzz switch statementFizzbuzz switch 语句
【发布时间】:2015-06-22 17:18:01
【问题描述】:

问题很长,但我认为这很奇怪。我在玩 ruby​​ switch 语句。创建了一个小的 fizzbuzz 函数来练习。

最初创建的代码是这样的

def fizzbuzz(start_num, end_num)
    fizzbuzz = []
    (start_num..end_num).each do |x|
        if x % 3 == 0 && x % 5 != 0
            fizzbuzz << "fizz"
        elsif x % 5 == 0 && x % 3 != 0
            fizzbuzz << "buzz"
        elsif (x % 3 == 0 && x % 5 == 0) 
            fizzbuzz << "fizzbuzz"
        else
            fizzbuzz << x.to_s
        end
    end
    fizzbuzz 
end 

按预期工作。然后想玩一个switch语句。所以我尝试了:

def fizzbuzz(start_num, end_num)
fizzbuzz = []
(start_num..end_num).each do |x|
    case x
    when x % 3 == 0 
        fizzbuzz << "fizz"
    when x % 5 == 0 
        fizzbuzz << "buzz"
    when (x % 3 == 0 && x % 5 == 0) 
        fizzbuzz << "fizzbuzz"
    else
        fizzbuzz << x.to_s
    end
end
fizzbuzz 

结束

这次代码只打印出转换为字符串的数字。然后我错误地尝试将 && 添加到每个 when 语句的末尾,就像这样

def fizzbuzz(start_num, end_num)
    fizzbuzz = []
    (start_num..end_num).each do |x|
        case x
        when x % 3 == 0 &&
            fizzbuzz << "fizz"
        when x % 5 == 0 &&
            fizzbuzz << "buzz"
        when (x % 3 == 0 && x % 5 == 0) &&
            fizzbuzz << "fizzbuzz"
        else
            fizzbuzz << x.to_s
        end
    end
    fizzbuzz 
end 

有趣的是,这会打印出正确的结果。这可能是一个微不足道的答案,但有谁知道为什么会这样?这对我来说似乎很奇怪。

【问题讨论】:

  • 因为一个switch语句只会执行一个分支,而你需要这个来打多个。对于case,FizzBu​​zz 不是一个很好的用例
  • @Brennan 不是,但这不是这里的问题; OP 的代码不需要任何失败行为。也许我误解了你的意思。
  • 一开始我看错了。这不是问题,一旦修复就会起作用,但它仍然显示出对这种结构如何工作的误解。它不需要要求任何失败的行为,但他肯定会尝试使用它。
  • @Brennan 我认为这更像是一个逻辑错误。如果 OP 试图依靠失败,他会得到所有三个,fizzbuzz,和fizzbuzz

标签: ruby switch-statement fizzbuzz


【解决方案1】:

when 语句正在执行逻辑 &amp;&amp;

这具有在条件为真时连接输出的副作用。

实际上提出的问题是,根据您的评论,when 语句似乎不起作用。问题是你写了case x,它正在现场评估x并将其与when表达式进行比较。

改为使用“裸case”,例如,

case
when (x % 3) == 0
  # etc

另请注意,这可能会被包裹得更紧,例如,

def fizzbuzz(start_num, end_num)
  (start_num..end_num).collect do |x|
    case
      when (x % 3) == 0
        "fizz"
      when (x % 5) == 0
        "buzz"
      when (x % 3 == 0 && x % 5 == 0)
        "fizzbuzz"
      else
        x.to_s
    end
  end
end

【讨论】:

    【解决方案2】:

    最后一段代码,让我们详细看一个when条件:

    when x % 3 == 0 &&
        fizzbuzz << "fizz"
    

    尽管有缩进,但它相当于:

    when x % 3 == 0 && fizzbuzz << "fizz"
    

    记住&amp;&amp; 是短路的。 &amp;&amp; 表达式如果为假则返回其第一个参数。否则,它的第二个参数被计算并作为结果返回。

    所以如果x % 3 == 0 为假,那么fizzbuzz &lt;&lt; "fizz" 不会被执行。如果x % 3 == 0 为真,则执行fizzbuzz &lt;&lt; "fizz"。完全符合预期。

    【讨论】:

    • 明白了,但是让我感到困惑的部分,我猜原来的问题中没有问,为什么即使 when x % 3 == 0 是真的,原来的 switch 语句也没有执行 fizzbuzz &lt;&lt; "fizz"
    • @AlexKonetchy 因为这不是 Ruby case 语句的工作方式;因为你写了case x,所以它正在将xwhen 表达式的值进行比较。
    猜你喜欢
    • 2014-11-19
    • 2018-01-11
    • 2013-09-15
    • 1970-01-01
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多