【问题标题】:Switch statement in SwiftSwift 中的 switch 语句
【发布时间】:2014-10-06 09:21:48
【问题描述】:

我正在学习 Swift 的语法,我想知道为什么下面的代码没有像我预期的那样工作:

for i in 1...100{

    switch (i){
    case 1:
        Int(i%3) == 0
        println("Fizz")
    case 2:
        Int(i%5) == 0
        println("Buzz")
    default:
        println("\(i)")
    }  
}

我想在每次数字可以被 3 整除(3、6、9、12 等)时打印 Fizz,并在每次可以被 5 整除时打印 Buzz。缺少哪一块拼图?

注意:我确实使用以下方法解决了它:

for ( var i = 0; i < 101; i++){

    if (Int(i%3) == 0){
        println("Fizz")
    }   else if (Int(i%5) == 0){
        println("Buzz")
    }   else {
        println("\(i)")
    }   
}

我想知道如何使用 Switch 解决这个问题。谢谢。

【问题讨论】:

  • 对于这个 If-Else 会比 Switch 好得多
  • 不,Bryan,我还没有阅读参考指南,谢谢您的链接。
  • 你有一个逻辑错误:对于任何可以被 3 AND 5 整除的数字,你只打印“Fizz”,而不是“Fizz Buzz”。
  • 我不熟悉游戏规则,我试着理解语法:)

标签: ios swift switch-statement


【解决方案1】:

switch 的行业标准行为可能导致类似于"Go to Fail" 的错误。

基本上,代码并不总是完全按照代码在阅读时的表现,这会导致代码审核员跳过严重的错误。

为了反驳这一点,Apple 决定 switch 语句在 Swift 中的工作方式不应与行业标准相同。特别是:

  • 每个案例结束时都会自动中断。执行多个 case 语句是不可能的。
  • 如果理论上有可能遗漏其中一个 case 语句,则代码根本无法编译。无论提供什么值,都会迅速执行其中一个 case 语句。如果您提供枚举,则必须处理每个枚举值。如果将新值添加到现有枚举中,则在添加新的 case 语句之前,代码不会编译。如果提供 32 位整数,则必须处理 32 位整数的所有可能值。

【讨论】:

  • Abhi,这很有趣,你的意思是我不能像使用 for-in 和“switch”语句那样使用这种枚举?它只假设处理“少量”的体面事件?
  • 请注意,您可以通过使用 fallthrough 关键字来避免自动中断,对于 32 位整数,可以使用 default 来处理未专门处理的所有情况。
  • @MattGibson 但这是一个自动失败,不会对下一个案例进行测试 - 所以不要在 OP 的案例中使用 oif
  • @Mark 我的评论(大约三年前!哇!)只是在这个答案中解决“不可能执行多个案例语句”,而不是 OP。
【解决方案2】:

使用此代码。你的逻辑是错误的。您的 Switch 语句没有找到 case 接受 1 和 2

class TEST1{
func print() -> Void{
    var i = 0
    for i in 1...100{
        if Int(i%3) == 0 {
            println("Fizz")
        }
        else if Int(i%5) == 0{
            println("Buzz")
        }
        else {
            println("\(i)")
        }   
    }
}
}
var x = TEST1()
x.print()

【讨论】:

  • 你看完我的整个帖子了吗?请再读一遍,我已经使用带有“if-else”的 for-in 语句进行了此操作。
  • Bhaskar 我问如何使用 switch 语句来解决这个任务。请更仔细地查看人们的要求。您的回答没有提供任何解决方案或线索,如何解决我的问题。谢谢。
【解决方案3】:

Swift 中的 Switch 语句支持值绑定。
这允许您将与特定条件(通过where 子句评估)匹配的值分配给临时变量(此处为xy):

for i in 1...100 {
    switch (i){
    case let x where x%3 == 0:
        println("Fizz")
    case let y where y%5 == 0:
        println("Buzz")
    default:
        println("\(i)")
    }
}

您也可以在案例正文中使用分配的临时值。

更新:
Matt Gibson 在 cmets 中指出,如果您不打算在案例正文中使用 temp var,则可以省略对 temp var 的赋值。
因此,上述代码的更简洁版本将是:

for i in 1...100 {
    switch (i){
    case _ where i%3 == 0:
        println("Fizz")
    case _ where i%5 == 0:
        println("Buzz")
    default:
        println("\(i)")
    }
}

旁注:您的 2 个代码示例略有不同(第一个使用范围 0-100 作为输入,而第二个使用 1-100)。我的示例基于您的第一个代码 sn-p。

【讨论】:

  • 您不需要“let x”、“let y”,因为您并没有真正使用这些值,您可以这样做,例如case _ where i%3 == 0:
  • 谢谢 - 我不知道。我更新了我的答案。
  • 非常感谢 weichsel 为我澄清这一点。
【解决方案4】:

FizzBuzz game 的常用规则 将每个 3 的倍数替换为“Fizz”,将每个 5 的倍数替换为“Buzz”,以及 “FizzBu​​zz”的 5 的每3 个倍数。

这可以通过元组(i % 3, i % 5) 上的switch 语句来完成。 请注意,_ 表示“任何值”:

for i in 1 ... 100 {
    switch (i % 3, i % 5) {
    case (0, 0):
        print("FizzBuzz")
    case (0, _):
        print("Fizz")
    case (_, 0):
        print("Buzz")
    default:
        print(i)
    }
}

【讨论】:

  • 在我看来,这似乎是对应该问的问题的正确答案:)
  • 这有点难以理解,但我认为这是正确的答案,谢谢马丁。
  • 漂亮的答案 :) 那是您使用语言的特定优势来解决问题的时候。
  • @Dx 同意了。我喜欢你如何一次打开多个值。 Python 甚至没有 switch 语句。
【解决方案5】:

这是可以做到的

var i = 0

switch i  {

case i where i % 5 == 0 && i % 3 == 0: print(" Fizz Buzz")
case i where i % 3 == 0 : print("Fizz")
case i where i % 5 == 0 : print("Buzz")
default: print(i)

}

【讨论】:

    【解决方案6】:

    对于来这里只是想知道如何在 Swift 中使用 switch 语句的人来说,这是一个更通用的答案。

    一般用法

    switch someValue {
    case valueOne:
        // executable code
    case valueTwo:
        // executable code
    default:
        // executable code
    }
    

    例子

    let someValue = "horse"
    
    switch someValue {
    case "horse":
        print("eats grass")
    case "wolf":
        print("eats meat")
    default:
        print("no match")
    }
    

    注意事项:

    • 不需要break 语句。这是默认行为。 Swift switch 案例不会“失败”。如果您希望他们在下一个案例中使用代码,您必须明确使用 fallthrough 关键字。
    • 每个案例都必须包含可执行代码。如果您想忽略一个案例,您可以添加一个 break 语句。
    • 案例必须详尽无遗。也就是说,它们必须涵盖所有可能的值。如果包含足够多的 case 语句不可行,则可以最后包含 default 语句以捕获任何其他值。

    Swift switch 语句非常灵活。以下部分包括其他一些使用它的方法。

    匹配多个值

    如果您使用逗号分隔值,则可以在一个案例中匹配多个值。这称为复合案例

    let someValue = "e"
    
    switch someValue {
    case "a", "b", "c":
        // executable code
    case "d", "e":
        // executable code
    default:
        // executable code
    }
    

    您还可以匹配整个间隔

    let someValue = 4
    
    switch someValue {
    case 0..<10:
        // executable code
    case 10...100:
        // executable code
    default:
        // executable code
    }
    

    您甚至可以使用 元组。本示例改编自documentation

    let aPoint = (1, 1)
    
    switch aPoint {
    case (0, 0):
        // only catches an exact match for first and second
    case (_, 0):
        // any first, exact second
    case (-2...2, -2...2):
        // range for first and second
    default:
        // catches anything else
    }
    

    值绑定

    有时您可能希望从switch 值创建一个临时常量或变量。您可以在 case 语句之后立即执行此操作。在任何使用值绑定的地方,它将匹配任何值。这类似于在上面的元组示例中使用_。以下两个示例是从documentation 修改而来的。

    let anotherPoint = (2, 0)
    
    switch anotherPoint {
    case (let x, 0):
        // can use x here
    case (0, let y):
        // can use y here
    case let (x, y):
        // can use x or y here, matches anything so no "default" case is necessary
    }
    

    您可以使用 where 关键字进一步优化匹配。

    let yetAnotherPoint = (1, -1)
    
    switch yetAnotherPoint {
    case let (x, y) where x == y:
        // executable code
    case let (x, y) where x == -y:
        // executable code
    case let (x, y):
        // executable code
    }
    

    进一步研究

    • 此答案旨在作为快速参考。请阅读完整的documentation 了解更多信息。不难理解。

    【讨论】:

      【解决方案7】:

      这是我使用 switch 语句来解决这类问题的两种方式。

      1>>使用where关键字

      func printNumberType(number : Int){
          
          switch number {
          case number where number % 3 == 0 && number % 5 == 0 :
              print("foo bar")
          case number where number % 3 == 0 :
              print("foo")
          case number where number % 5 == 0 :
              print("bar")
          default :
              print("Number is not divisible by 3 and 5")
          }
      }
      

      2>>使用值组合

      func printNumberByMultipleValues(number : Int){
          
          let combination = (number % 3,number % 5)
          
          switch combination {
          case (0,0):
              print("foo bar")
          case (0,_) :
              print("foo")
          case (_,0) :
              print("bar")
          default :
              print("Number is not divisible by 3 and 5")
          }
      }
      

      这里是多值类型的更接近的例子。

      var printNumberByMultipleValues : (Int)->() = { number in
          
          let combination = (number % 3,number % 5)
          
          switch combination {
          case (0,0):
              print("foo bar")
          case (0,_) :
              print("foo")
          case (_,0) :
              print("bar")
          default :
              print("Number is not divisible by 3 and 5")
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-21
        相关资源
        最近更新 更多