Подтвердить что ты не робот

Оператор switch в Swift

Я изучаю синтаксис 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)")
    }  
}

Я хочу напечатать Fizz каждый раз, когда число делится на 3 (3, 6, 9, 12 и т.д.) и печатает Buzz каждый раз, когда он делится на 5. Какой фрагмент головоломки отсутствует?

Примечание. Я разрешил это, используя следующее:

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. Спасибо.

4b9b3361

Ответ 1

Обычные правила для игра FizzBuzz должны заменять каждый кратный 3 "Fizz", каждый кратный 5 "Buzz", и каждый кратный как 3 , так и 5 на "FizzBuzz".

Это можно сделать с помощью оператора 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)
    }
}

Ответ 2

Операторы switch в привязках значений поддержки Swift.
Это позволяет присвоить значение, которое соответствует определенному условию (оценивается с помощью предложения 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)")
    }
}

Вы также можете использовать назначенное значение temp в корпусе.

Update:
Мэтт Гибсон отмечает в комментариях, что вы можете опустить назначение временному 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). Мой образец основан на вашем первом фрагменте кода.

Ответ 3

Это более общий ответ для людей, которые приезжают сюда, просто желая узнать, как использовать инструкцию switch в Swift.

Общее использование

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. Это поведение по умолчанию. Быстрые случаи 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. Это не сложно понять.

Ответ 4

Стандартное поведение коммутатора может привести к ошибкам, похожим на "Перейти к ошибке" .

В основном код не всегда делает то, что он выглядит, как код будет делать при чтении по нему, что приводит к тому, что аудиторы кода пропускают критические ошибки.

Чтобы противостоять этому, Apple решила, что операторы switch не должны работать одинаково в Swift как отраслевой стандарт. В частности:

  • В конце каждого случая происходит автоматический разрыв. Невозможно выполнить более одного оператора case.
  • Если теоретически возможно, чтобы один из аргументов case был упущен, код вообще не будет компилироваться. В быстрых случаях оператор всегда будет выполнять, независимо от того, какое значение предоставляется. Если вы указываете перечисление, каждое значение перечисления должно обрабатываться. Если новое значение добавляется к существующему перечислению, код не будет компилироваться до тех пор, пока не будут добавлены новые аргументы case. Если вы указываете 32-битное целое число, вы должны обрабатывать все возможные значения 32-битного int.

Ответ 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

Используйте этот код. Ваша логика ошибочна. В вашем заявлении на коммутатор не найден случай 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()