Оператор 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. Спасибо.
Ответы
Ответ 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()