Swift 中的 Switch 语句

问题描述 投票:0回答:8

我正在学习 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 解决这个问题。谢谢你。

ios swift switch-statement
8个回答
110
投票

FizzBuzz 游戏的通常规则 将每个 3 的倍数替换为“Fizz”,将每个 5 的倍数替换为“Buzz”,并且 “FizzBuzz”的 3 5 的每一个倍数。

这可以通过元组上的 switch 语句来完成

(i % 3, i % 5)

。
请注意,
_
 表示“任何值”:

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) } }
    

24
投票
Swift 中的 Switch 语句支持值绑定。

这允许您将与特定条件匹配的值(通过
where

 子句评估)分配给临时变量(此处为 
x
y
):

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)在评论中指出,如果您不打算在案例正文中使用临时变量,则可以省略对它的分配。
因此,上述代码的更简洁版本是:

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 上运行)。我的示例基于您的第一个代码片段。


20
投票
对于那些来这里只是想知道如何在 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 }

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

文档 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

 语句之后立即执行此操作。在任何使用值绑定的地方,它将匹配任何值。这与上面元组示例中使用 
_
 类似。以下两个示例是根据
文档
修改的。 
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 }

进一步学习

这个答案旨在作为快速参考。请阅读完整的

文档
    了解更多信息。不难理解。
这是可以做到的

4
投票
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) }

交换机的行业标准行为可能会导致类似于 

1
投票
的错误。

基本上,代码并不总是完全按照代码在阅读时看起来的方式执行,这导致代码审核员跳过关键错误。

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

每个案例结束时都会自动休息。不可能执行多个 case 语句。

    如果理论上有可能漏掉其中一个 case 语句,那么代码根本无法编译。在 swift 中,无论提供什么值,case 语句之一都将始终执行。如果您提供枚举,则必须处理每个枚举值。如果将新值添加到现有枚举中,则在添加新的 case 语句之前,代码将无法编译。如果您提供 32 位整数,则必须处理 32 位整数的每个可能值。
以下是我使用 switch 语句解决此类问题的两种方法。

0
投票

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") } }

正在研究这个问题,并提出了两种读起来有点不同的解决方案。就我个人而言,我更喜欢 switch 语句,并在我的索引号上使用 .isMultiple(of: 3) 。

0
投票
选项 1 |开关

for i in 1...100 { switch (i.isMultiple(of: 3), i.isMultiple(of: 5)) { case (true, true): print("\(i) | FizzBuzz") case (true, false): print("\(i) | Fizz") case (false, true): print("\(i) | Buzz") default: print(i) } }

选项2 |如果语句
for i in 1...100 {
    if i.isMultiple(of: 3) && i.isMultiple(of: 5) {
        print("\(i) | FizzBuzz")
    } else if i.isMultiple(of: 3) {
        print("\(i) | Fizz")
    } else if i.isMultiple(of: 5) {
        print("\(i) | Buzz")
    } else {
        print(i)
    }
}

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

-1
投票
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()


© www.soinside.com 2019 - 2024. All rights reserved.