`switch`-like模式匹配控制流语句匹配任何和所有真实案例?

时间:2017-11-10 21:57:07

标签: swift switch-statement pattern-matching programming-languages control-flow

注意:这个问题不是要求帮助解决FizzBu​​zz。请不要发布只解决FizzBu​​zz的答案。此问题的答案应与匹配多个 true switch个案

相关

使用FizzBuzz

考虑在Swift中尝试switch statement解决方案
func fizzBuzz(forInt int: Int) -> String {
    var output = ""
    switch 0 {
    case (int % 3): output += "Fizz"
    case (int % 5): output += "Buzz"
    default:
        output = String(int)
    }

    return output
}

// FAILS
assert(fizzBuzz(forInt: 15) == "FizzBuzz", "15 should output `FizzBuzz`, not `Fizz`!")

迭代15上的正确输出应该是"FizzBuzz",因为15可以被3和5整除。

但上面的程序会输出"Fizz",因为只会执行第一次传递case

Swift docs state

  

switch语句根据成功匹配的第一个模式执行适当的代码块。

似乎有一个类似的,switch类似的语句与任何真实案例匹配而不仅仅是第一个。

模式匹配模式目前可用于以下情况:

  

您可以在switch语句的case标签,do语句的catch子句或if,while,guard或for-in语句的case条件中使用这些模式。

在Swift中似乎不可能匹配多个模式。考虑的选项:

下通

Switch fallthrough允许一个已执行的案例落入并执行物理下一个案例,但没有实际测试case语句。它不允许在匹配时执行多个任意无序的情况。

多个if语句

多个if语句会产生所需的行为,但出于同样的原因而烦恼switch通常比if-else块更受欢迎。

if (i % 3 == 0) {
    // ...
}
if (i % 5 == 0) {
    // ...
}

即在每种情况下重新说明正在测试的变量,没有编译器保护我们正在针对多个案例评估相同的单个变量等。

元组等

是的,可以做一些事情,比如打开一个元组来产生正确的输出值。但这涉及在案例中复制代码。

switch (i % 3, i % 5) {
case (0, 0):
    output += "FizzBuzz"
case (0, _):
    output += "Fizz"
case (_, 0):
    output += "Buzz"

这个问题的目标是只有2个案例为“Fizz”和“Buzz”。 组合执行真实案例应该产生“FizzBu​​zz”,而不是单独的第3个复制字符串的案例。

相关:

Switch to match multiple cases from OptionSetType

问题:

是否存在与switch类似的模式匹配控制流语句,它匹配任何和所有真实案例?如果不是在Swift中,是否所有语言都包含这样的功能?

2 个答案:

答案 0 :(得分:0)

这种循环嵌套的switch语法按顺序执行每个真实案例,而不仅仅是第一个真实案例。

for i in 1...100 {
    var output = ""

    for eachCase in 0...1 {
        switch (eachCase, 0) {
        case (0, i % 3): output += "Fizz"
        case (1, i % 5): output += "Buzz"
        default: break }
    }

    if output.isEmpty {
        output = String(i)
    }

    print(output)
}

我会留给读者来确定这种情况比其他方法更好的情况,例如多个if语句。

答案 1 :(得分:0)

有一个Swift演化提议在Switch案例中引入continue语句,这将恢复与剩余案例的模式匹配。

  

[swift-evolution] [Pitch]介绍继续切换语句

     

此提案通过引入continue来完成switch语句的控制流转移套件。此更改添加了许多开发人员期望(但未获得)fallthrough的功能。

     

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160704/023955.html

     

https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a

     

介绍continue表示“执行此case子句后恢复模式匹配”。它提供了比交换机中当前存在的更细微的控制。