티스토리 뷰

iOS/Swift-Documents

Swift 5.5 Control Flow -5

malrang-malrang 2022. 1. 27. 23:20

빵쟁이가 ios 개발자가 되기위해 정독하고자 작성한 글 입니다!
표현이 이상하거나 잘못번역된 부분이 있을수 있습니다.
혹 누군가 읽다 잘못된 부분이 있으면 댓글로 알려주세요!

Control Flow

Swift는 다양한 제어 흐름 명령문을 제공합니다.제어흐름 명령문에는 while, if, guard, switch, break, continue 이있으며
특정 조건에 따라 여러번실행 하는 while, 코드의 다른 분기를 실행하기 위한 if, guard, switch가 있으며
break 및 continue와 같은 명령문은 실행 흐름을 코드의 다른 지점으로 전송합니다.
또한 Swift는 Array, Dictionary, range, String 을 쉽게 다룰수 있는 for-in 루프를 제공합니다.
Swift의 switch 구문은 C언어의 것보다 더 강력한 기능들을 제공한다.
케이스들을 튜플, 특정 타입에 대한 캐스트를 포함해서 좀 더 많은 패턴으로 구성할 수 있다.
Switch의 케이스 일치 값은 임시 상수 혹은 변수에 담길 수 있다. 복잡한 조건은 각 케이스의 where 절로 표현될 수 있다.

**For-In Loops##

for-in 루프를 사용하여 배열의 항목, 숫자 범위 또는 문자열의 문자와 같은 값들을 꺼내어 사용할수있다.

예시 에서는 for-in 루프를 사용하여 배열의 Element 들을 하나씩 꺼내어 사용합니다.

let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names {
    print("Hello, \(name)!")
}
// Hello, Anna!
// Hello, Alex!
// Hello, Brian!
// Hello, Jack!

Dictionary 에서 사용하면 키-값 에 접근 할 수 있습니다. Dictionary의 각 항목은 key-value(키, 값) 튜플로 반환됩니다.
반환된 값들을 명시적으로 선언한 상수로 나누어 나타낼 수도 있다.

아래 코드 예제에서 사전의 key는 animalName이라는 상수로 분해되고 사전의 value은 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 을 사용해도 순서를 보장 하지않는다.
기존 Dictionary에 새로운 key와 value 를 넣어도 몇번째 순서인지 알수없다. 순서를 보장해주는 타입이 아니기때문임!

숫자 범위와 함께 for-in 루프를 사용할 수도 있습니다.

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는 루프의 각 반복이 시작될 때마다 값이 자동으로 설정되는 상수이다. 즉 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"

이 코드의 경우 루프반복 할때마다 개별 카운터 값이 필요하지 않습니다. 코드는 단순히 루프를 올바른 횟수만큼 실행합니다.
루프 변수 대신 밑줄 문자(_)를 사용하면 개별 값이 무시되고 루프가 반복될 때마다 현재 값에 액세스할 수 없습니다.

반개방 범위 연산자(..<)를 사용할수도있다.

let minutes = 60
for tickMark in 0..<minutes {
    // render the tick mark each minute (60 times)
}

이경우엔 0부터59 번까지 총 60번 반복하라는뜻이다.
마지막 숫자 60은 포함하지 않는다는 뜻이다.

for-in 구문을 사용할 때 stride(from:to:by), stride(from: through: by:) 함수를 사용하면 반복을 몇 단계씩 건너뛰고 수행할 수 있다.
즉 각각의 개별값이 필요한게 아니라 몇번씩 건너뛴 값들이 필요할경우 사용할수있다.
이때 stride(from:to:by)는 to 값에 어디까지 수행하라는 뜻이다.

let minuteInterval = 5
for tickMark in stride(from: 0, to: minutes, by: minuteInterval) {
    // render the tick mark every 5 minutes (0, 5, 10, 15 ... 45, 50, 55)
}

stride(from:through:by:) 를 사용하여 닫힌 범위를 사용할 수도 있습니다.
stride(from: through: by:)는 through 값까지 수행하라는 뜻이다.

let hours = 12
let hourInterval = 3
for tickMark in stride(from: 3, through: hours, by: hourInterval) {
    // render the tick mark every 3 hours (3, 6, 9, 12)
}

While Loops

while 루프는 조건이 거짓이 될 때까지 반복 수행합니다.
이러한 종류의 루프는 반복 횟수를 알 수 없을 때 가장 잘 사용됩니다. Swift는 두 가지 종류의 while 루프를 제공합니다.

  • while은 반복을 시작할때 마다 조건을 검사 합니다.
  • repeat-while은 반복이 끝날 때마다 조건을 검사 합니다.

While

while 루프는 단일 조건을 검사하고 시작합니다.
조건이 참이면 조건이 거짓이 될 때까지 반복 수행합니다.

다음은 while 루프의 일반적인 형식입니다.

예시는 뱀과 사다리 의 간단한 보드게임 입니다.

게임의 규칙은 다음과 같습니다.

  • 보드에는 25개의 발판이 있으며 목표는 25발판 이상의 발판에 도착하는 것입니다.
  • 시작은 보드의 1이아닌 0부터 시작합니다.
  • 각 턴에 주사위를 굴리고 위의 점선 화살표로 표시된 수평 경로를 따라 해당 칸만큼 이동합니다.
  • 당신의 차례가 사다리의 맨 아래에서 끝나면, 당신은 그 사다리를 올라갑니다.
  • 당신의 턴이 뱀의 머리에서 끝나면 당신은 그 뱀의 아래로 이동합니다.

게임 보드는 Int 값의 배열로 표현됩니다. 크기는 finalSquare라는 상수를 기반으로 합니다.
finalSquare는승리 조건을 확인하는 데 사용됩니다.
플레이어가 0에서 시작하기 때문에 보드는 25가 아닌 26개의 0 Int 값으로 초기화됩니다.

let finalSquare = 25
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]은 +08과 로 작성하며 나머지들도 동일한 이유입니다.

var square = 0
var diceRoll = 0
while square < finalSquare {
    // roll the dice
    diceRoll += 1
    if diceRoll == 7 { diceRoll = 1 }
    // move by the rolled amount
    square += diceRoll
    if square < board.count {
        // if we're still on the board, move up or down for a snake or a ladder
        square += board[square]
    }
}
print("Game over!")

위의 예는 주사위 굴림에 대한 매우 간단한 접근 방식을 사용합니다. 난수(랜덤한숫자)를 생성하는 대신 diceRoll 값의 0 으로 시작합니다.
while 루프를 반복 할 때마다 diceRoll이 1씩 증가하고 7만큼 커졌는지 조건을 검사합니다.
값이 7일 때마다 값이 1로 재설정됩니다. 결과는 항상 1, 2, 3, 4, 5, 6, 1, 2 으로 나오게 됩니다.
주사위를 굴린 후 플레이어는 주사위 값만큼 앞으로 이동합니다.
플레이어가 25칸 이상으로 이동했을 수 있으며, 이 경우 게임이 종료됩니다.
25보다 높은수로 이동할경우를 방지하기 위해 코드는 square가 보드 어레이의 count 속성보다 작은지 확인합니다.
(배열의 범위 바깥쪽을 접근하는것을 방지하기위해! 배열 범위보다 초과 한 범위에 접근하게되면 오류발생!)
유효하면 보드[square]에 저장된 값이 현재 값에 추가되어 플레이어를 사다리나 뱀을 위아래로 이동합니다.

그런 다음 현재 while 루프 실행이 종료되고 루프의 조건을 확인하여 루프를 다시 실행해야 하는지 확인합니다.
플레이어가 25칸 이상으로 이동한 경우 루프의 조건은 거짓으로 평가되고 게임이 종료됩니다.

while 루프가 시작될 때 게임의 길이가 명확하지 않기 때문에 이 경우에 while 루프가 적절합니다. 대신 특정 조건이 충족될 때까지 루프가 실행됩니다.

Repeat-While

while 루프의 다른 변형인 repeat-while 루프는 루프의 조건을 고려하기 한번 실행한후. 조건이 거짓일 때까지 루프를 계속 반복합니다.

Note
Swift의 repeat-while 루프는 다른 언어의 do-while 루프와 유사합니다.

다음은 반복문 루프의 일반적인 형식입니다.

여기 뱀과 사다리 예제가 있습니다. while 루프가 아닌 Repeat-While로 작성되었습니다.
finalSquare, board, square 및 diceRoll의 값은 while 루프와 똑같은 방식으로 초기화됩니다.

let finalSquare = 25
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
var square = 0
var diceRoll = 0

이 버전의 게임에서 루프의 첫 번째 작업은 사다리나 뱀이 있는지 확인하는 것입니다.
보드의 어떤 사다리도 플레이어를 25칸으로 바로 데려가지 못하므로 사다리를 올라가서 게임에서 이기는 것은 불가능합니다.
게임을 시작할때 플레이어는 0 에서 시작합니다.

repeat {
    // move up or down for a snake or ladder
    square += board[square]
    // roll the dice
    diceRoll += 1
    if diceRoll == 7 { diceRoll = 1 }
    // move by the rolled amount
    square += diceRoll
} while square < finalSquare
print("Game over!")

코드가 뱀과 사다리를 확인한 후 주사위를 굴리고 플레이어는 diceRoll 만큼 앞으로 이동합니다.
그런 다음 현재 루프 실행이 종료됩니다.

루프의 조건(square < finalSquare)은 이전과 동일하지만, 반복문을 실행할때 처음에 조건을 검사하지 않습니다.
repeat-while 루프의 구조는 이전 예제의 while 루프보다 이 게임에 더 적합합니다.
repeat-while 루프에서 square += board[square]는 루프의 while 조건이 정사각형이 여전히 26미만의 발판에 있음을 확인한 후에 실행됩니다.
while 루프 버전에서 있던 if square < board.count 조건을 사용하지 않아도됩니다.

Conditional Statements (조건문)

특정 조건에 따라 코드를 수행하는 것은 유용하다.
이렇게 조건에 따라 코드를 수행하게 만드는 것이 Conditional Statements이다.
Swift는 조건문을 만드는 방법을 2가지 제공한다.
하나는 if문이고 하나는 switch 문이다.
if는 몇 개 안되는 간단한 조건들을 확인할 때 쓰이고 switch는 좀 더 많고 복잡한 조건을 확인할 때 쓰이면 좋다.

If

가장 간단한 형태의 if 문에는 단일 if 조건이 있습니다.
해당 조건이 참인 경우에만 일련의 명령문을 실행합니다.

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도(물의 어는점) 이하인지 확인합니다.
조건이 true 라면 실행구문의 메시지가 출력됩니다.
그렇지 않으면 메시지가 출력되지 않고 넘어가게 됩니다.

if 문은 if 조건이 false인 상황을 대비해 else 절을 실행시킬수 있습니다. 이러한 명령문은 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."

이 두 분기 중 하나는 항상 실행됩니다.
온도가 화씨 40도까지 증가했기 때문에 더 이상 스카프를 착용하라고 조언할 만큼 춥지 않으므로 대신 else 의 실행구문이 실행됩니다.

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 sunscreen.")
} else {
    print("It's not that cold. Wear a t-shirt.")
}
// Prints "It's really warm. Don't forget to wear sunscreen."

따뜻한 온도에 응답하기 위해 else if 문이 추가되었습니다.
마지막 else 절은 남아 있고 너무 덥지도 너무 춥지도 않은 온도에 대한 응답을 출력합니다.

else는 선택사항이며 사용하지않아도 if문을 작성할수 있습니다.

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 구문은 특정 값을 몇 가지 조건으로 비교하여 true로 나오는 조건들 중 첫 번째 패턴의 명령을 수행하는 구문이다.
가장 간단한 switch 구문은 switch와 case만 사용한 구문이다.

switch 의 일반적인 형태

if 문의 본문과 마찬가지로 각 case는 별도의 코드 실행 분기입니다.
switch 문은 실행해야 하는 분기를 결정합니다.

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"

위의 코드에서 comeCharacter가 조건들에 확인될 값이다.
여기서 comeCharacter은 "z"인데 이러한 조건이 있기 때문에 해당 조건의 명령이 수행된다.
switch에서 default 구문은 만약 값이 모든 조건에 false가 결과로 나오게 되면 수행될 명령을 선언하는 구문이다.

No Implicit Fallthrough

C언어와 Objective-C와 다르게 Swift에서의 switch 문은 기본적으로 어떤 경우에 만족할 경우 해당 경우의 아랫부분을 확인하지 않는다.
또한 switch 문에서 break 문을 요구하지 않는다.
즉 첫 번째로 일치하는 조건을 만나서 명령을 수행하자마자 switch 문을 빠져나온다.
이렇기 때문에 두 개 이상의 조건에 만족하는 경우를 방지할 수 있다.
각각의 조건은 하나 이상의 실행문이 포함되어야 한다.

let anotherCharacter: Character = "a"
switch 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.

위의 코드는 case"a": 에 실행해야할 것이 없기때문에 오류를 일으킨다.

여러 조건을 한case에 넣어 사용할수도 있다.
조건은 , 쉼표로 구분한다.

let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a", "A":
    print("The letter A")
default:
    print("Not the letter A")
}
// Prints "The letter A"

Interval Matching

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이 실행되어 switch 외부로 값이 전송됩니다."dozens of"switch"

Tuples

튜플을 사용하여 동일한 switch문에서 여러 값을 테스트할 수 있습니다.
튜플의 각 요소는 다른 값 또는 값 간격에 대해 테스트할 수 있습니다.
또는 와일드카드 패턴이라고도 하는 밑줄 문자()를 사용하여 가능한 값과 일치시킵니다.

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"

위의 코드에서 보면 주어진 점은 (1,1)이다.
이 점이 해당되는 조건은 (-2...2, -2...2)이다. 위의 코드에서 볼 수 있듯 튜플의 각각의 원소에 대해 조건을 확인할 수 있다.

Value Bindings

switch의 case에서 일시적인 상수나 변수를 선언해서 사용할 수 있다.

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"

위의 코드에서 let x, let y와 같이 일시적으로 상수나 변수를 선언하여 사용할 수 있고 이렇게 선언되면 다음 케이스에서 사용할 때에는 다시 선언해 줄 필요가 없다.
위의 코드에서 마지막에 선언된 let(x, y)는 마치 default와 비슷한 역할을 하게 된다.
따라서 default 케이스가 필요하지 않게 된다.

Where

switch 구문에서는 where 절을 사용하여 추가 조건을 확인할 수 있다.

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"

위의 코드와 같이 추가적인 조건을 주어 switch 구문을 사용할 수 있다.

Compound Cases

,로 구분하여 여러 조건들을 하나의 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) isn't a vowel or a consonant")
}
// Prints "e is a vowel"

Compound Cases에서도 value binding을 사용할 수 있다.

let stillAnotherPoint = (9, 0)
switch stillAnotherPoint {
case (let distance, 0), (0, let distance):
    print("On an axis, \(distance) from the origin")
default:
    print("Not on an axis")
}
// Prints "On an axis, 9 from the origin"

Control Transfer Statements

Control transfer Statements 코드의 한 부분에서 다른 부분으로 제어를 전송하여 코드가 실행되는 순서를 변경합니다.
Swift에는 5개의 Control transfer Statements이 있습니다.

  • continue
  • break
  • fallthrough
  • return
  • throw

Continue

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 를 사용하여 현재 작업을 중단하고 다음 반복문으로 넘어가라 라고 하는것과 같다.
모음이나 공백과 일치할때마다 print문이 실횅되지않고 다음 반복문을 실행하게되어 모음과 공백이없는 문자가 된것을 확인할수 있다.

Break

break명령문은 전체 제어 흐름 명령문의 실행을 즉시 종료합니다 .

Break in a Loop Statement

반복문안에서 Break를 사용하게되면 반복문에서 탈출하여 다음코드를 실행하게끔 할수있다.
특정 조건에 부합했다면 반복문을 탈출시키고 싶을때 사용합니다.

Break in a Switch Statement

switch 내에서 사용되는 break경우 switch가 즉시 실행을 종료하고 switch 밖의 다음코드를 실행하게된다.
이러한 코드는 switch문에서 몇 가지 케이스를 무시할 때 사용할 수 있다. Swift의 switch문은 케이스마다 반드시 실행문이 존재해야 하기 때문에 무시하고 싶은 케이스에 break를 사용하면 된다.
default 에서 사용가능!

let numberSymbol: Character = "三"  // Chinese symbol for the number 3
var possibleIntegerValue: Int?
switch numberSymbol {
case "1", "١", "一", "๑":
    possibleIntegerValue = 1
case "2", "٢", "二", "๒":
    possibleIntegerValue = 2
case "3", "٣", "三", "๓":
    possibleIntegerValue = 3
case "4", "٤", "四", "๔":
    possibleIntegerValue = 4
default:
    break
}
if let integerValue = possibleIntegerValue {
    print("The integer value of \(numberSymbol) is \(integerValue).")
} else {
    print("An integer value couldn't be found for \(numberSymbol).")
}
// Prints "The integer value of 三 is 3."

Fallthrough

Swift에서 switch는 case를 실행한후 다음 case로 넘어가지 않습니다.
즉, switch첫 번째 case가 일치하는 경우 case 실행구문을 실행한후 즉시 전체 명령문이 실행을 완료된것으로 처리합니다.
하지만 C언어에서는 한 케이스를 만족해도 break 코드가 없다면 다음 케이스도 확인을 하는데 이 때문에 오류가 발생한다. 그래서 늘 케이스의 마지막에 break를 넣어줘야 한다. 하지만 swift에서도 C언어에서처럼 한 케이스를 만족하더라도 다음 케이스도 보고 싶다면 fallthrough를 사용하면 된다.

예씨 코드에서 integerToDescribe = 5이므로 첫 번째 케이스의 조건에 맞게 된다.
하지만 fallthrough가 있기 때문에 다음에 있는 default 구문의 명령도 수행하게 된다.

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."

Labeled Statements

Swift에서는 다른 루프와 조건문 안에 또 다른 루프와 조건문을 중첩하여 복잡한 제어 흐름 구조를 만들 수 있다.
루프와 조건문은 모두 해당 break명령문을 사용하여 실행을 조기에 종료할 수 있습니다.
이럴 때 종료할 루프와 조건문을 명시적으로 나타내 주는 게 효과적일 수 있다. 마찬가지로 continue문도 어떤 루프에 적용되는 것인지 명시하는것이 유용하다. 이러한 방법을 사용하기 위해 명령문 레이블을 사용하여 루프와 조건문을 표시할 수 있다. 명령문 레이블은 해당 루프 혹은 조건문 앞에 명시해 주면 된다.

Labeled Statements (레이블이 지정된 조건문,반복문) 의 사용 예시

예제에서는 이 장의 앞부분에서 본 Snakes and Ladders 게임 의 개조된 버전에 대해 레이블이 지정된 루프 와 함께 break및 continue문을 사용합니다.이번에는 게임에 추가 규칙이 있습니다.

  • 이기려면 정확히 25번 칸에 착지해야 합니다.
    특정 주사위를 굴려서 25칸을 넘어설 경우, 25칸에 도달하는 데 필요한 정확한 숫자가 나올 때까지 다시 굴려야 합니다.
    게임판은 기존과 동일합니다.

    finalSquare, board, square, diceRoll의 값은 이전과 동일한 방식으로 초기화됩니다.이 버전의 게임은 while루프와 switch명령문을 사용하여 게임의 논리를 구현합니다.
    루프에는 Snakes and Ladders 게임의 기본 게임 루프임을 나타내기 위해 while호출된 명령문 레이블이 있습니다.
    while루프의 조건은 정사각형 25에 정확히 착지해야 하기위한것으로 수정합니다. while square != finalSquare
  • gameLoop: while square != finalSquare { diceRoll += 1 if diceRoll == 7 { diceRoll = 1 } switch square + diceRoll { case finalSquare: // diceRoll will move us to the final square, so the game is over break gameLoop case let newSquare where newSquare > finalSquare: // diceRoll will move us beyond the final square, so roll again continue gameLoop default: // this is a valid move, so find out its effect square += diceRoll square += board[square] } } print("Game over!")
  • let finalSquare = 25 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 var square = 0 var diceRoll = 0

주사위는 각 루프가 시작될 때 굴립니다.
플레이어를 즉시 이동하는 대신 루프는 switch명령문을 사용하여 이동 결과를 고려하고 이동이 허용되는지 여부를 결정합니다.

  • break를 사용하여 주사위를 굴려서 플레이어를 마지막 칸으로 옮기면 게임이 끝납니다.
  • continue를 사용하여 주사위를 던져 이동할 값이 25를 넘어가면 루프 반복을 종료하고 루프의 다음 반복을 시작하게합니다.(주사위 다시던지게 합니다.)

Early Exit

if문과 비슷하게 guard문도 조건의 결과에 따라 명령문을 실행한다.

guard문의 명령문은 반드시 조건이 true 여야 실행 가능하다. 그렇기 때문에 guard문에는 항상 else문이 함께 있어야 한다.

func greet(person: [String: String]) {
    guard 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."

명령문의 조건이 충족 else 를 무시하고 guard뒤에 코드를 실행한다.
guard문에서도 binding을 사용할 수 있는데 이때 선언된 변수나 상수는 guard문이 선언된 나머지 코드에서도 사용할 수 있다. 만약 조건이 false라면 else문의 명령을 수행한다. 이때 else문의 명령은 코드를 종료하기 위해 return, break, continue, throw와 같은 제어 전송 명령문으로 작성되거나 fatalError(_: file: line:)과 같이 리턴되지 않는 함수 또는 메서드를 호출해야 한다.

Checking API Availability

Swift는 API 사용 가능성 확인을 지원하기 때문에 실수로 사용할 수 없는 API를 사용하는 일을 방지할 수 있다.
컴파일러는 SDK의 사용 가능 정보를 사용하여 코드에 사용된 모든 API가 프로젝트에 지정된 배포 대상에서 사용 가능한지 확인해 준다. 만약 사용할 수 없는 API를 사용하려고 하면 컴파일 오류를 발생시킨다.
개발자는 if, guard 문을 사용해서 avilability condition을 사용할 수 있다.

if #available(iOS 10, macOS 10.12, *) {
    // Use iOS 10 APIs on iOS, and use macOS 10.12 APIs on macOS
} else {
    // Fall back to earlier iOS and macOS APIs
}

위의 코드는 Ios10이상, macos10.12 이상에서만 실행하도록 만든것이다.
마지막 인수 * 는 필수이고 다른 플랫폼에서 if에서 지정한 최소 배포 버전 이상의 버전에서만 실행되도록 지정한다.

사용예시

Swift 공식문서

https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html

 

The Basics — The Swift Programming Language (Swift 5.6)

The Basics Swift is a new programming language for iOS, macOS, watchOS, and tvOS app development. Nonetheless, many parts of Swift will be familiar from your experience of developing in C and Objective-C. Swift provides its own versions of all fundamental

docs.swift.org

 

https://icksw.tistory.com/

 

PinguiOS

iOS 개발자가 되기 위해 iOS 공부, Swift 공부, CS 공부를 하고 있습니다.

icksw.tistory.com

 

'iOS > Swift-Documents' 카테고리의 다른 글

Swift Generics  (0) 2022.07.24
Swift 5.5 Functions -6  (0) 2022.02.04
Swift 5.5 Collection Types -4  (0) 2022.01.27
Swift 5.5 Strings and Characters -3  (0) 2022.01.25
swift5.5 공식문서 Basic Operators -2  (0) 2022.01.23
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함