Swift는 다양한 제어 흐름(control flow)구문을 제공합니다. 이것은 여러번 작업을 수행하는 while 루프를 포함하고 조건에 따라 다르게 실행되는 if, guard, switch 구문과 코드에서 다른 포인트로 실행 플로우를 전달하는 break 와 continue 를 포함합니다. Swift는 또한 배열, 딕셔너리, 범위, 문자열, 그리고 다른 연속적인 것에 대한 반복을 쉽게 만들어주는 for-in 루프를 제공합니다. Swift의 switch 구문은 C와 유사한 언어의 해당 구문보다 훨씬 더 강력합니다. 케이스들은 간격 매치, 튜플, 그리고 특정 타입으로의 캐스트를 포함하여 다른 많은 패턴을 비교할 수 있습니다. switch 케이스에서 매치된 값을 케이스 문 안에서 사용할 수 있는 임시의 상수 또는 변수로 사용이 가능하고 복잡한 매칭조건은 각 케이스에 대해 where 절로 표현될 수 있습니다.
배열에 아이템, 범위의 숫자, 또는 문자열에 문자와 같은 연속된 것에 대해 for-in 루프를 사용하여 반복할 수 있습니다. 이 예제는 for-in 루프를 사용하여 배열의 아이템을 반복합니다.
let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names{
print("Hello, \(name)!")
}
//Hello, Anna!
//Hello, Alex!
//Hello, Brian!
//Hello, Jack!
딕셔너리의 키-값 쌍 접근을 위해 반복을 사용할 수 있습니다. 딕셔너리의 각 아이템은 딕셔너리가 반복될 때 (key, value) 튜플로 반환되고 for-in 루프 바디 내에서 사용하기 위해 (key, value) 튜플의 멤버를 명시적으로 이름을 가진 상수로 분해할 수 있습니다. 아래의 예제에서 딕셔너리의 키는 animalName 상수로 분해되고 딕셔너리의 값은 legCount 상수로 분해됩니다.
let numberOfLegs = ["spider": 8, "ant":6, "cat": 4]
for (animalName, legCount) in numberOfLegs{
print("\(animalName)s have \(legCount) legs")
}
// cats have 4 legs
// ants have 6 legs
// spiders have 8 legs
Dictionary 의 콘텐츠는 기본적으로 순서가 없으며 반복으로 가져올 아이템에 대한 순서를 보장하지 않습니다. 특히 아이템을 딕셔너리에 삽입하는 순서는 아이템이 반복되는 순서를 정의하지 않습니다.
숫자 범위에 대해 for-in 루프를 사용할 수도 있습니다. 이 예제는 5의 배수 항목을 몇개 출력합니다.
for index in 1...5{
print("\(index) times 5 is \(index*5)")
}
//1 times 5 is 5
//2 times 5 is 10
//3 times 5 is 15
//4 times 5 is 20
//5 times 5 is 25
이 반복되는 시퀀스는 닫힌 범위 연산자(...)를 사용하여 표시되는 1부터 5까지의 숫자 범위 입니다. index의 값은 범위의 첫번째 숫자(1)로 설정되고 루프 안의 구문이 실행됩니다. 이 경우 루프는 index의 현재 값을 5배 하여 출력하는 하나의 구문만 포함됩니다. 구문이 실행된 후에 index의 값은 범위의 두번째 값(2)로 업데이트 되고 print() 함수가 다시 호출됩니다. 이 프로세스는 범위의 끝에 도달할 때까지 계속 됩니다.
위의 예제에서 index는 루프의 각 반복이 시작할 때 자동으로 설정되는 값인 상수입니다. 따라서 index를 사용하기 전에 선언할 필요가 없습니다. let 선언 키워드가 필요없이 루프 선언에 포함되어 암시적으로 선언됩니다. 시퀀스로 부터 각 값이 필요하지 않으면 변수 이름의 위치에 언더바를 사용하여 값을 무시할 수 있습니다.
let base = 3
let power = 10
var answer = 1
for _ in 1...power{
answer *= base
}
print("\(base) to the power of \(power) is \(answer)")
// Prints "3 to the power of 10 is 59049"
위의 예는 한 숫자의 값을 다른 숫자의 제곱으로 계산합니다.1로 시작하고 10으로 끝나는 닫힌 범위를 사용하여 시작값 1에 3을 10번 곱합니다. 이 계산에서 루프의 각 카운터 값은 불필요 합니다. 즉 이코드는 간단하게 올바른 숫자만큼 실행됩니다. 루프 변수 위치에 사용된 언더바 문자 _ 는 각 값을 무시하고 루프의 각 반복동안 현재 값에 접근하는 것을 제공하지 않습니다. 어떤 상황에선 양 끝점을 포함하는 닫힌 범위를 사용하지 않을 수 있습니다. 시계 페이스에 매 분마다 눈금을 그리는 것을 생각해 봅시다. 0분을 시작으로 60개의 눈금을 그려야 합니다. 이럴 경우 반열림 범위 연산자(..<)를 사용하여 가장 최소값은 포함하지만 최대 값은 포함되지 않게 사용할 수 있습니다.
let minumtes = 60
for tickMark in 0..<minutes {
// render the tick mark each minute(60times)
}
어떤 사용자는 UI에 더 적은 눈금을 원할 수도 있습니다. 매 5분마다 눈금을 그리기 원할 수 있습니다. 원하지 않는 눈금을 건너뛰기 위해 stride(from:to:by:) 함수를 사용하십시오.
let minuteInterval = 5
for tickMark in stride(from: 0, to: minutes, by: minuteInterval){
//render the tick mark every 6 minutes(0, 5, 10, 15 ... 45, 50 , 55)
}
while 루프는 조건이 false가 될 때까지 구문의 집합을 수행합니다. 이러한 루프는 첫번째 반복이 시작되기 전에 반복 횟수를 알 수 없을 때 가장 잘 사용됩니다. Swift 는 2종류의 while 루프를 제공합니다.
while 은 루프가 시작할 때마다 조건을 비교합니다.repeat - while 은 루프가 끝날 때 마다 조건을 비교합니다.while 루픈느 단일 조건을 평가함으로 시작합니다. 조건이 true 이면 조건이 false가 될 때까지 구문의 집합은 반복 됩니다. 여기 while 루프의 기본 형식 입니다.

이 예제는 Snakes and Ladders 게임을 플레이 합니다.
게임의 규칙은 아래와 같습니다.
게임 보드는 Int 값의 배열로 표현됩니다. 크기는 finalSquare라는 상수를 기반으로 하며 배열을 초기화하고 나중에 예제에서 승리 조건을 확인 하는데 사용됩니다. "정사각형 0"에서 플레이어는 시작하기 때문에 보드는 0 Int 값을 포함하여 25가아닌 26의 크기로 초기화 합니다.
let finalSquare = 26
var board = [Int](repeating: 0, count: finalSquare + 1)
그런 다음 일부 사각형은 뱀과 사다리에 대해 더 구체적인 값을 갖도록 설정 됩니다. 사다리 기반의 정사각형은 보드의 위로 이동하기 때문에 양수를 가지는 반면에 뱀 머리의 정사각형은 보드의 아래로 이동하기 때문에 음수를 가집니다.
board[03] = +08; board[06] = +11; board[09]= +09; board[10] = +02; board[14] = -10; board[19]= -11; board[22] = -02; board[24] = -08
정사각형 3은 정사각형 11로 이동하는 사다리 바닥이 포함됩니다. 이것을 표현하기 위해 board[03] 은 정수값 8 과 동등한 +08을 대입합니다. 값과 구문을 정렬하기 위해 단항 더하기 연산자는 단항 빼기 연산자를 명시적으로 사용하고 10보다 작은 숫자의 앞에 0을 채웁니다.
var square = 0
var diceRoll = 0
while square < finalSquare{
diceRoll += 1
if diceRoll == 7 {diceRoll = 1}
square += diceRoll
if square < board.count{
square += board[square]
}
}
print("Game over!")
위의 예는 주사위 굴리기에 매우 간단한 접근 방식을 사용합니다. 난수를 생성하는 대신에 diceRoll은 0의 값으로 시작합니다. 매 while 루프를 실행할 때마다 diceRoll 은 1씩 증가하고 너무 커졌는지 확인합니다. 반환된 값이 7과 같을 때마다 주사위 굴림이 너무 커지므로 값을 1로 재설정 합니다. 그 결과 diceRoll 값은 항상 1,2,3,4,5,6,1,2 등과 같이 시퀀스 입니다.
while 루프의 다른 하나는 루프의 조건을 판단하기 전에 루프 블럭을 처음에 한번 먼저 통과하는 repeat-while 루프가 있습니다. 조건이 false가 될 떄까지 루프를 반복합니다.
여기 repeat-while 루프의 일반적인 형식입니다.

조건이 포함되는 코드 기반의 다른 조각을 실행할 때 유용한 경우가 있습니다. 에러가 발생하거나 값이 너무 크거나 작을 때 메세지를 출력하려고 할 때 코드의 별도의 부분을 실행하고 싶을 수 있습니다. 이러한 동작을 위해 코드 조건부의 부분을 만들어야 합니다. Swift는 코드에 조건부를 추가하는 방법은 if 구문과 switch 구문으로 2가지 제공합니다. 일반적으로 if 구문은 가능한 결과가 적은 간단한 조건에 적합합니다. switch 구문은 가능한 결과가 여러개이며 더 복잡한 조건에 적합하고 실행해야 할 적절한 코드 분기를 선택해야 하는 패턴 매칭 상태에 유용합니다.
가장 간단한 형식으로 if 구문은 단일 if 조건을 갖습니다. 조건이 true 일 경우에만 구문을 실행합니다.
var temperatureInFahrenheit = 30
if temperatureInFahrenheit <= 32 {
print("It's very cold. Consider wearing a scarf.")
}
// Prints "It's very cold. Consider wearing a scarf."
위 예제는 기온이 화씨 32도 보다 작거나 같은지 확인합니다. 만약 화씨 32도 보다 작거나 같으면 메세지가 출력됩니다. 반대는 메세지가 출력되지 않으며 코드는 if 구문의 닫힘 중괄호 이후를 계속 실행합니다.
if 구문은 if 조건이 false 일 때 그밖의 다른 구문을 제공할 수 있습니다. 이 구문은 else 키워드로 표기합니다.
temperatureInFahrenheit = 40
if temperatureInFahrenheit <= 32{
print("It's very cold. Consider wearing a scarf.")
}else {
print("It's not that cold. Wear a t-shirt.")
}
//Prints "It's not that cold. Wear a t-shirt."
2개의 중괄호 중 하나는 항상 실행됩니다. 기온이 증가하여 화씨 40도를 가지므로 더이상 추워서 스카프르 해야 한다고 충고하지 않으며 else 구문이 실행됩니다.
추가 절을 고려하기 위해 여러 if 구문을 연결할 수 있습니다.
temperatureInFahrenheit = 90
if temperatureInFahrenheit <= 32 {
print("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
print("It's really warm. Don't forget to wear sunscrenn.")
} else{
print("It's not that cold. Wear a t-shirt.")
}
//Prints "It's really warm. Don't forget to wear sunscreen."
여기 if 구문은 특정 따뜻한 기온에 응답하기 위해 추가 되었습니다. 마지막 else 절은 남아있고 어떤 기온이 너무 따뜻하거나 너무 춥지 않을 경우에 응답을 출력합니다. 그러나 마지막 else 절은 옵셔널이고 이 조건이 완벽하게 필요가 없으면 제외할 수 있습니다.
temperatureInFahrenheit = 72
if temperatureInFahrenheit <= 32{
print("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
print("It's really warm. Don't forget to wear sunscreen.")
}
기온이 너무 춥지도 따뜻하지도 않아 if 또는 else if 조건에 포함되지 않으므로 아무런 메세지가 출력되지 않습니다.
switch 구문은 값을 고려하고 가능한 여러 일치 패턴과 비교합니다. 그런다음 첫번째로 일치하는 패턴을 기반으로 적절한 코드 블럭을 실행합니다.switch 구문은 여러 가능한 상태에 응답하기 위해 if 구문의 대체 구문으로 제공합니다.
가장 간단한 형식으로 switch 구문은 하나 이상의 같은 타입의 값과 비교합니다.

모든 switch 구문은 각각 case 키워드로 시작하는 여러개의 가능한 케이스로 구성되어 있습니다. 특정 값과 비교하는 것 외에도 Swift는 각 케이스에 대해 더 복잡한 일치 패턴을 지정하는 여러가지 방법을 제공합니다.
if 구문ㄴ의 바디와 같이 각 case는 코드 실행 부분이 분리되어 있습니다. switch 구문은 실행 될 부분을 선택합니다. 이 절차를 값에 스위칭이라 알려져 있습니다. 모든 switch 구문은 완벽해야 합니다. 이것은 고려중인 타입의 가능한 모든 값은 switch 케이스 중 하나와 일치해야 합니다. 가능한 모든 값에 대한 케이스를 제공하는 것이 적절하지 않은 경우 명시적으로 해결되지 않은 모든 값을 포함하도록 기본 케이스를 정의할 수 있습니다. 기본 케이스는 default 키워드로 나타내고 항상 마지막에 위치합니다.
이 예제는 switch 구문을 사용하여 someCharacter의 소문자를 고려합니다.
let someCharacter: Character = "z"
switch someCharacter {
case "a":
print("The first letter of the alphabet")
case "z":
print("The last letter of the alphabet")
default:
print("Some other character")
}
//Prints "The last letter of the alphabet"
switch 구문의 첫번째 케이스는 영어 알파벳의 첫번째 문자인 a 와 일치하고 두번째 케이스는 마지막 문자인 z와 일치합니다. switch는 모든 알파벳 문자 뿐만 아니라 모든 가능한 문자에 대한 케이스를 가지고 있어야 하므로 이 switch 구문은 a와 z을 제외한 다른 모든 문자는 default 케이스를 사용합니다. 이렇게 함으로 switch 구문은 완벽하다는 것을 보장합니다.
C와 Objective-C의 switch 구문과 다르게 Swift의 switch 구문은 기본적으로 각 케이스의 바닥에서 다음 케이스로 바로 실행되지 않습니다.
명시적으로 break 구문 요청 없이 처음 일치하는 switch 케이스가 완료되자마자 switch 구문 전체가 끝납니다. 이러한 점은 switch 구문을 더 안전하고 C의 switch 구문보다 사용하기 쉽게 해주고 실수로 switch 케이스가 하나 이상 실행되는 것을 피할 수 있습니다.
각 케이스의 바디는 반드시 적어도 하나의 실행가능한 구문이 포함되어야 합니다. 아래의 코드는 첫번째 케이스가 비어 있으므로 유효하지 않습니다.
let anotherCharacter: Character = "a"
swith anotherCharacter {
case "a": //Invalid, the case has an empty body
case "A":
print("The letter A")
default:
print("Not the letter A")
{
//This will report a compile-time error.
C의 switch 구문과 다르게 이 switch 구문은 "a"와 "A"둘다 일치하지 않습니다. case "a": 에 어떠한 실행가능한 구문이 없기 때문에 컴파일 때 에러가 발생합니다. 이 접근 방식은 한 케이스에서 다른 케이스로의 우발적인 실행을 방지하고 의도를 더 명확하게 하고 안전한 코드를 만듭니다. "a"와 "A" 모두 일치하는 단일 케이스의 switch를 만드려면 두 값을 콤마로 구분하여 하나로 결합하여 구성합니다.
let anotherCharacter: Character ="a"
switch anotherCaracter{
case "a", "A":
print("The letter A")
default:
print("Not the letter A")
{
// Prints "The letter A"
읽기 쉽게 하기위해 합성 케이스는 여러줄로 작성할 수도 있습니다.
switch 케이스 안에 값은 간격을 포함하여 확인할 수 있습니다. 이 예제는 숫자 간격을 사용하여 모든 크기의 숫자에 대한 자연어 갯수를 제공합니다.
let approximateCount = 62
let countedThings = "moons orbiting Saturn"
let naturalCount: String
switch approximateCount{
case 0:
naturalCount = "no"
case 1..<5:
naturalCount = "a few"
case 5..<12:
naturalCount = "several"
case 12..<100:
naturalCount = "dozens of"
case 100..<1000:
naturalCount = "hundreds of"
default:
naturalCount = "many"
}
print("There are \(naturalCount) \(countedThings).")
//Prints "There are dozens of moons orbiting Saturn."
위의 예제에서 approximateCount는 switch 구문에서 판단됩니다. 각 case는 숫자 값 또는 간격을 비교합니다. approximateCount의 값은 12와 100사이에 속하므로 naturalCount 는 "dozens of" 값이 할당되고 switch 구문을 빠져나옵니다.
같은 switch 구문에 여러 값인 튜플을 사용할 수 있습니다. 튜플의 각 요소는 다른 값 또는 값의 간격을 판단할 수 있습니다. 가능한 어떠한 값도 일치하도록 와일드카드 패턴으로 알려진 언더바 문자(_)를 사용할 수 있습니다.
아래 예제는 타입 (Int, Int)의 간단한 튜플로 표현된(x,y) 포인트를 가지며 그래프에서 분류합니다.
let somePoint = (1, 1)
switch somePoint{
case (0, 0):
print("\(somePoint) is at the origin")
case (_, 0):
print("\(somePoint) is on the x-axis")
case (0, _):
print("\(somePoint) is on the y-axis")
case (-2...2, -2...2):
print("\(somePoint) is inside the box")
default:
print("\(somePoint) is outside of the box")
}
//Prints "(1, 1) is inside the box"
switch 구문은 점이 원점(0,0) 인지, 빨간색 x축 위에 있는지, 초록색 y축 위에 있는지, 원점이 중심인 파란색 4*4 박스 내부에 있는지 외부에 있는지 판단합니다.
C와 다르게 swift는 여러 switch 케이스가 같은 값 또는 값들인지 고려하는 것이 가능합니다. 사실 점 (0,0)은 이 예제의 모든 4개의 케이스에 일치합니다. 그러나 여러개가 일치할 수 있다면 첫번째 일치하는 케이스가 항상 사용됩니다. 점 (0,0)은 첫번째 case(0,0)와 일치하고 다른 모든 케이스는 무시됩니다.
switch 케이스는 일치하는 값 또는 값들을 임시적 상수 또는 변수로 이름을 가질 수 있으며 케이스 바디 안에서 사용할 수 있습니다. 값은 케이스의 바디 내부에서 임시적 상수 또는 변수로 바인드 되기 때문에 이러한 동작을 값 바인딩(Value binding)이라 합니다.
아래 예제는 튜플의 타입(Int, Int) 로 표현된 점 (x,y)를 가지며 그래프에 분류합니다.
let anotherPoint = (2,0)
switch anotherPoint{
case (let x, 0):
print("on the x-axis with an x value of \(x)")
case (0, let y):
print("on the y-axis with a y value of \(y)")
case let (x,y):
print("somewhere else at (\(x), \(y))")
//Prints "on the x-axis with an x value of 2"
이 switch 구문은 점이 빨간색인 x축에 있는지, 초록색인 y축에 있는지, 또는 다른 곳(축 위가 아닌)에 있는지 판단합니다.
이 3개의 switch 케이스는 자리 상수 x와 y를 선언하며 anotherPoint에서 임시적으로 하나 또는 2개의 튜플 값을 받습니다. 첫번째 케이스인 case (let x, 0) 는 y점 값이 0이고 점의 x값은 임시적 상수 x에 할당한 것과 일치합니다. 비슷하게 두번째 케이스 case(0, let y)는 점 x 값이 0이고 점의 y값은 임시적 상수 y에 할당한 것과 일치합니다.
임시적 상수가 선언된 후에 케이스의 코드 블럭 안에서 사용될 수 있습니다.
이 switch 구문은 default 케이스를 가지고 있지 않습니다. 마지막 케이스 case let(x, y)는 어떠한 값도 일치할 수 있는 2개의 상수를 가지는 튜플로 선언합니다. anotherPoint는 2개의 값이 튜플이기 때문에 가능한 남아있는 모든 케이스와 일치하며 switch 구문을 완벽하게 하기위해 default 케이스가 필요치 않습니다.
switch 케이스는 추가 조건으로 where 절을 사용할 수 있습니다.
아래 예제는 그래프에 (x, y)를 분류합니다.
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
print("(\(x), \(y)) is on the line x == -y")
case let (x, y):
print("(\(x), \(y) is just some arbitrary point")
Prints "(1, -1) is on the line x. == -y"
같은 바디를 공유하는 여러개의 스위치 케이스는 case 다음에 각 패턴 사이에 콤마로 구분하여 여러개의 패턴으로 결합 될 수 있습니다. 어떤 패턴이 일치한 케이스로 고려됩니다. 패턴이 길면 여러줄로 작성할 수 있습니다. 예를 들어:
let someCharacter: Character = "e"
switch someCharacter {
case "a", "e", "i", "o", "u":
print("\(someCharacter) is a vowel")
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
"n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
print("\(someCharacter) is a consonant")
default:
print("\(someCharacter) is not a vowel or a consonant")
}
//Prints "e is a vowel"
switch 구문의 첫번째 케이스는 영어의 5개의 소문자 모음이 일치합니다. 비슷하게 두번째 케이스는 모든 영어 소문자 자음이 일치합니다. 마지막으로 default 케이스는 다른 어떠한 문자와 일치합니다. 혼합 케이스(Compound cases)는 값 바인딩을 포함할 수도 있습니다. 혼합 케이스의 모든 패턴은 값 바인딩의 같은 집합을 포함해야 하고 각 바인딩은 홉합 케이스에 모든 패턴으로 부터 같은 타입의 값을 얻어야 합니다. 혼합 케이스 부분이 일치하는 것과 상관없이 케이스의 바디에 코드는 바인딩을 위해 값에 항상 접근할 수 있고 값은 항상 같은 타입을 가집니다.
let stillAnotherPoint = (9,0)
switch stillAnotherPoint {
case (let distance, 0), (0, let distance):
print("On an axis, \(distnace) from the origin")
default:
print("Not on an axis")
//Prints "On an axis, 9 from the origin"
제어 변경 구문은 한 코드에서 다른 코드로 제어를 변경하여 코드가 실행되는 순서를 변경합니다. Swift는 5개의 제어 변경 구문이 있습니다.
continue 구문은 루프를 통해 다음 반복을 시작하려고 멈추기위해 부릅니다. 이것은 루프를 완전히 벗어나지 않고 "현재 루프 반복은 완료 되었습니다."라고 말합니다. 아래 예제는 비밀의 퍼즐 구문을 생성하기 위해 소문자 문자열에서 모음과 공백을 삭제합니다.
let puzzleInput = "great minds think alike"
var puzzleOutput = ""
let charactersToRemove : [Character] = ["a", "e", "i", "o", "u", " "]
for character in puzzleInput {
if charactersToRemove.contains(character) {
continue
}
puzzleOutput.append(character)
}
print(puzzleOutput)
//Prints "grtmndsthnklk"
위 코드는 모음 또는 공백이 일치하면 현재 반복의 루프를 종료하고 즉시 다음 반복을 시작하기 위해 continue 키워드를 호출합니다.
break 구문은 전체 제어흐름 구문을 즉시 종료합니다. break 구무은 switch 내부나 루프 구문에서 switch 또는 루프 구문을 다른경우보다 일찍 종료시킬 때 사용될 수 있습니다.
루프 구문 내에서 사용할 때 break는 루푸의 실행을 즉시 종료하고 제어를 루프의 닫기 중괄호 다음으로 이전합니다. 루프의 현재 반복으로 부터 코드는 더이상 실행되지 않고 루프의 반복은 더이상 시작되지 않습니다.
switch 구문 내에서 사용할 때 break는 switch 구문을 즉시 종료하고 제어를 switch 구문의 닫힌 중괄호 다음으로 이동시킵니다.
이러한 동작은 일치할 때 사용될 수 있고 switch 구문에서 하나 또는 그 이상의 케이스를 무시할 때 사용됩니다. Swift의 switch 구문은 완벽하고 빈 케이스를 허락하지 않기 때문에 의도를 명시하기 위해 의도적으로 케이스를 일치시키고 무시해야 하는 경우가 있습니다. 무시할 케이스의 전체 본문으로 break구문을 작성하여 이를 수행합니다. 해당 케이스가 switch 구문과 일치하면 케이스 내부의 break 구문이 switch 구문의 실행을 즉시 종료합니다.
Swift에서 switch 구문은 각 케이스의 맨 아래에서 다음 케이스로 넘어가지 않습니다. 첫번째 케이스가 일치하자마자 switch 구문의 실행은 완료됩니다. 반대로 C는 다음 케이스로 넘어가는 것을 막기 위해 모든 switch케이스 마지막에 명시적으로 break구문을 넣어야 합니다. 기본적으로 다음 케이스로 넘어가지 않는다는 것은 Swift의 switch구문이 C의 대응문 보다 훨씬 간결하고 예측 가능하다는 것을 의미하므로 실수로 여러 switch 케이스를 실행하지 않습니다. C처럼 다음 케이스로 넘어가려면 fallthrough 키워드로 케이스 별로 동작을 선택할 수 있습니다. 아래 예에서 fallthrough를 사용하여 숫자의 설명을 생성합니다.
let integerToDescribe = 5
var description = "The number \(integerToDescribe) is"
switch integerToDescribe{
case 2, 3, 5, 7, 11, 13, 17, 19:
description += " a prime number, and also"
fallthrough
default:
description += " an integer."
}
print(description)
//Prints "The number 5 is a prime number, and also an integer"
이 예제는 description 이라 불리는 새로운 String 변수를 선언하고 초기값을 할당합니다. 이 함수는 switch 구문을 사용하여 integerToDescribe의 값을 고려합니다. integerToDescribe의 값이 목록에서의 소수 중 하나이면 소수라는 것을 나타내는 텍스트를 description뒤에 추가합니다. 그러면 fallthrough 키워드를 사용하여 default 케이스 또한 동작하게 됩니다. default 케이스는 추가 설명을 덧붙이고 swith 구문은 완료됩니다. integerToDescribe 의 값이 목록에 없는 소수이면 첫번째 switch 케이스와 전혀 일치하지 않습니다. 특정 케이스가 없기 때문에 integerToDescribe는 default 케이스와 일치됩니다. switch 구무 실행이 완료된 후에 숫자의 설명은 print함수를 사용하여 출력됩니다.
Swift에서 복잡한 제어흐름 구조는 생성하기 위해 루프와 조건 구문내에 다른 루프와 조건 구문을 중첩할 수 있습니다. 그러나 루프와 조건 구문은 모두 실행을 조기 종료하기 위해 break 구문을 사용할 수 있습니다. 따라서 break 구문으로 종료될 루프나 조건 구문에 라벨을 붙이는 것이 유용할 때가 있습니다. 마찬가지로 여러개의 중첩된 루프를 가지고 있다면 continue 구문에 영향을 받는 루프에 라벨을 붙이는 것이 유용할 수 있습니다. 이러한 목적을 달성하기 위해 루프 구문 또는 조건 구문에 구문 라벨을 표기할 수 있습니다. 조건 구문에서 라벨이 있는 구문에 실행을 종료하기 위해 break 구문과 구문 라벨을 사용할 수 있습니다. 루프 구문에서 라벨이 있는 구문에 실행을 종료하거나 이어서 진행하기 위해 break 또는 continue 구문과 구문 라벨을 사용할 수 있습니다. 라벨이 있는 구문은 구문의 소개자 키워드와 같은 줄에 위치하고 바로 다음에 콜론이 옵니다. 여기 예제는 while 루프에 대한 구문의 예입니다. 모든 루프와 switch 구문에 대해 동일합니다.

if 구문과 같이 gurad 구문은 표현식의 부울 값에 따라 구문을 실행합니다. guard 구문은 guard 구문의 다음을 실행하기 위해 반드시 조건이 참인 것을 요구하기 위해 사용합니다. if 구문과 반대로 guard 구문은 항상 else 절을 가지고 있습니다. else 절 안의 코드는 조건ㅇ니 참이 아닐 경우에 실행됩니다.
func greet(person:[String: String]){
guarud let name = person["name"] else{
return
}
print("Hello \(name)!")
guard let location = person["location"] else {
print("I hope the weather is nice near you.")
return
}
print("I hope the weather is nice in \(location).")
}
greet(person: ["name": "John"])
//Prints "Hello John!"
//Prints "I hope the weather is nice near you."
greet(person: ["name" : "Jane", "location" : "Cupertino"])
//Prints "Hello Jane!"
//Prints "I hope the weather is nice in Cupertino."
guard 구문의 조건이 충족되면 코드 실행은 guard 구문의 닫는 중괄호 다음으로 이어집니다. 조건의 일부로 옵셔널 바인딩을 사용하여 값이 할당된 모든 변수 또는 상수는 guard 문이 존재하는 나머지 코드 블럭에서 사용할 수 있습니다. 조건이 충족되지 않으면 else 안의 코드가 실행됩니다. 이 블럭은 반드시 guard 구문이 존재하는 코드 블럭을 종료하기 위해 제어를 이동해야 합니다. return, break, continue, throw 또는 fatalError(_:file:line:)과 같은 되돌아가지 않는 함수 또는 메서드 같은 구문으로 제어를 이동할 수 있습니다. 필요조건을 위한 guard 구문 사용은 같은걸 확인하는 if 구문과 비교하요 코드를 더 읽기 좋게 해줍니다. 이를 통해 일반적으로 실해오디는 코드를 else 블럭으로 래핑하지 않고 작성할 수 있으며 요구에 충족하지 않는 부분을 요구사항 근처에서 처리할 수 있도록 해줍니다.
Swift는 주어진 타겟에서 사용 불가능한 API를 실수로 사용하는 것을 막기위해 사용 가능한 API 확인을 제공합니다. 컴파일러는 사용된 API가 프로젝트에 특정 타겟에서 사용 가능한지 확인하기 위해 SDK 안에 사용 가능한 정보를 사용합니다. SWift는 사용 불가능한 API에 대해 컴파일 시 에러를 발생합니다.
사용하려는 API를 런타임에 사용할 수 있는지 여부에 따라 if 또는 guard 구문에서 가용성 조건을 사용하여 코드 블럭을 조건부로 실행합니다. 컴파일러는 해당 코드 블럭의 API를 사용할 수 있는지 확인할 때 가용성 조건의 정보를 사용합니다.
if #available(iOS 10, macOS 10.12, *){
//use iOS 10 APIs on iOS, and use macOS 10.12 APIs on macOS
} else {
// Fall bakc to earlier iOS and macOS APIs
}
iOS에서 위의 특정 가용성 조건의 if 구문의 바디는 iOS 10 이후 버전에서만 실행되고 macOS에서는 macOS10.12 이후 버전에서만 실행됩니다. 마지막 인자 *는 필수이며 다른 플랫폼에서 if의 바디가 최소 타겟 버전에서 실행되도록 지정 합니다. 일반적인 형식에서 가용성 조건은 플랫폼 이름 및 버전 목록을 사용합니다.