Swift 2: expression pattern of type 'Bool'

2019-01-23 19:04发布

I'm doing this problem set "FizzBuzz", and my switch statement is giving me some problems, here's my code:

func fizzBuzz(n: Int) -> String {   
    switch n {
    case n % 3 == 0: print("Fizz")
    case n % 5 == 0: print("Buzz")
    case n % 15 == 0:print("FizzBuzz")
    }
    return "\(n)"
}

If you could provide me with pointers / hints, instead of giving me the correct code, that would be swell :D I'd prefer solving it myself, but a few hints could get me out of this hole.

4条回答
唯我独甜
2楼-- · 2019-01-23 19:15

Try using "case let where":

func fizzBuzz(n: Int) -> String {
    let result: String
    switch n {
    case let n where n % 3 == 0 && n % 5 == 0:
        result = "FizzBuzz"
    case let n where n % 3 == 0:
        result = "Fizz"
    case let n where n % 5 == 0:
        result = "Buzz"
    default:
        result = "none"
    }
    print("n:", n, "result:", result)
    return result
}
查看更多
手持菜刀,她持情操
3楼-- · 2019-01-23 19:18

A bit late, but just to add to the various answers. I believe the elegant solution to use now is this:

func fizzBuzz(n: Int) {
    switch (n%3==0, n%5==0) {
    case (true, false):
        print("Fizz")
    case (false, true):
        print("Buzz")
    case (true, true):
        print("FizzBuzz")
    default:
        print(n)
    }
}

Swift can switch on tuples (sorta structs, but constructed on the fly without a definition somewhere else in the code). Then in the case labels you can check for multiple values at once, which is ideal for FizzBuzz!

To break it down a bit, this part

(n%3==0, n%5==0)

generates a tuple with two boolean values. Then a case label like this

case (true, true)
    print("FizzBuzz")

checks if both these values (essentially n%3==0 and n%5==0) are true and prints "FizzBuzz"

Doing it like this makes it very easily expandable. You can add a third definition to the switch argument and a third true/false to your cases and your FizzBuzz can become a FizzBuzzJazz. You can also name the values in the tuple if you want by simply adding labels like

switch (fizz: n%3==0, buzz: n%5==0, jazz: n%7==0) {
case (fizz: true, buzz: false, jazz: true)
    print("FizzJazz")
}

making the code more readable in some cases.

查看更多
何必那么认真
4楼-- · 2019-01-23 19:20

Just two things wrong:

(1) Your cases are boolean expressions, so you want to compare them against true, not n;

(2) You need a default case. So:

func fizzBuzz(n: Int) -> String {
    switch true {
    case n % 3 == 0: print("Fizz")
    case n % 5 == 0: print("Buzz")
    case n % 15 == 0: print("FizzBuzz")
    default: print("Shoot")
    }
    return "\(n)"
}
查看更多
▲ chillily
5楼-- · 2019-01-23 19:34

I know its little late for this answer. I am updating the answer of @Leo Dabus with an another approach which is written and tested on Xcode 7.3.1 and Swift 2.2.

func fizzBuzz(n: Int) -> String {
 switch n {
  case _ where n % 3 == 0:
    print("Fizz")
  case _ where n % 5 == 0:
    print("Buzz")
  case _ where n % 15 == 0:
    print("FizzBuzz")
  default:
    print("none")
 }
 return "\(n)"
}

Thanks, Hope this helped.

查看更多
登录 后发表回答