[Swift] 4. 조건문(if), 반복문(while)

Hoojeong Kim·2021년 9월 6일
0

Swift Base

목록 보기
6/22
post-thumbnail

흐름 제어

프로그램을 작성하다보면 특정 조건에서 코드를 실행해야 하거나, 특정 명령어를 반복해야하는 일이 종종 발생한다. 이럴 때 사용하는 것이 바로 조건문과 반복문이다.

대부분의 프로그래밍 언어에서 조건문과 반복문을 다루지만 스위프트는 다른 언어와 차이가 있으니 유의해야 한다. 스위프트의 흐름 제어 구문에서는 소괄호()를 대부분 생략할 수 있으나, 중괄호{}는 생략할 수 없다.

따라서 이번에는 조건문과 반복문에 대해 공부하고자 한다.


조건문

조건문으로는 if 구문과 swift 구문이 있다. 스위프트에는 guard 구문도 있으나, 이는 추후에 다루고자 한다.

if 구문

if 구문은 대표적인 조건문으로 if, else 등의 키워드를 사용하여 구현할 수 있다. 정수, 실수 등 0이 아닌 모든 값을 참으로 취급하여 조건 값이 될 수 있었던 다른 언어와는 달리 스위프트의 if 문은 조건의 값이 꼭 Bool 타입 이어야 한다.

if 구문의 기본적인 사용은 다음과 같다.

if 조건 수식1 {
    실행 코드
}
else if 조건 수식2 {
    실행 코드
}
else if 조건 수식3 {
    실행 코드
}
else {
    실행 코드
}

else if는 몇 개가 이어져도 상관 없으며 else 블록은 없어도 상관이 없다.

if 문에서 여러 개의 조건을 순차적으로 대조하다가 특정 조건에 일치한다면 그에 해당하는 코드를 실행하고, 그 다음에 이어진 조건문은 조건에 충족하더라도 실행되지 않고 조건문을 빠져나온다.
이때 각 블록의 조건에는 소괄호()를 붙이지 않아도 상관이 없다.


다음은 if 구문을 사용해 두 변수의 값을 비교하는 코드이다.

let first: Int = 1
let second: Int = 2

if first > second {
    print("first > second")
} else if first < second {
    print("first < second")
} else {
    print("first == second")
}
first > second

switch 구문

기본 문법이라 할 수 있는 switch 구문은 다른 언어와 비교했을 때 많이 달라진 문법 중 하나이다. switch 구문도 if문 처럼 소괄호()를 생략할 수 있으며, break 키워드 또한 선택적으로 사용한다.
즉, case 내부의 코드를 실행하면 break 없이도 switch 구문이 종료된다는 뜻인데, 이 방식은 예상치 못한 실수를 중이는 데도 큰 도움이 된다.


스위프트에서 switch 구문의 case를 연속 실행하려면 fallthrough 키워드를 사용한다.

C 언어에서는 조건에 정수 타입만 들어갈 수 있었지만, 스위프트에서는 다양한 값이 들어갈 수 있다. 다만 각 case에 들어갈 비교 값은 입력 값과 데이터 타입이 같아야 한다.
또, 비교될 값이 명확히 한정적인 값(열거형 값 등)이 아닐 때는 default를 꼭 작성해야 한다.

각 case에는 범위 연산자나 where 절을 사용해 조건을 확장할 수 있다.


swift 구문의 사용은 기본적으로 다음과 같다.
swift 입력 값 {
case 비교 값1 :
    살행 코드
case 비교 값2 :
    실행 코드
    // 이번 case를 마치고 switch 구문을 탈출하지 않음
    fallthrough
case 비교 값3, 비교 값4, 비교 값5 : // 한 번에 여러 값 비교 가능
    실행 코드
    break   // break 키워드의 사용은 선택 사항
default :
    실행 코드
}

다음은 간단한 switch 구문 활용이다.
let integerValue: Int = 5

switch integerValue {
case 0:
    print("Value == Zero")
case 1...10:
    print("Value == 1~10")
    fallthrough
case Int.min..<0, 101..<Int.max:
    print("Value < 0 or Value > 100")
    break
default:
    print("10 < Value <= 100")
}
Value == 1~10
Value < 0 or Value > 100

위의 코드처럼 case의 비교 값에 단 하나의 값 뿐만이 아니라 범위 연산자를 넣을 수도 있다.

결과에서 "Value < 0 or Value > 100"이 출력된 이유는, 두 번째 블록에서 fallthrough 키워드를 사용하여 세 번째 블록도 실행되도록 했기 때문이다.
만약 integerValue의 값이 0이었다면, "Value == zero"만 출력됐을 것이다.

범위 연산자는 정수 뿐만이 아니라 부동소수 타입에도 사용할 수 있으며, switch 구문의 입력 값으로는 숫자 뿐만이 아니라 문자, 문자열, 열거형, 튜플 등의 타입 값도 사용할 수 있다.


타 언어에서는 아래와 같은 방식으로 사용이 가능하다.
int num = 3;

switch (num) {
    case 0:
    case 1:
    case 2:
    case 3:
        print("num >= 3");
    default:
        print("num < 3")
}

위 코드는 java를 사용해 작성한 switch 코드이다. java나 C 등은 처럼 case 안의 실행 코드를 생략하며 사용할 수 있지만, 스위프트에서 이러한 방식을 사용하게 되면 오류가 발생한다.

따라서 위와 같은 코드를 작성하고 싶을 때는 fallthrough 키워드를 사용해야 한다.

let num: Int = 3

switch num {
case 0:
    fallthrough
case 1:
    fallthrough
case 2:
    fallthrough
case 3:
    print("num >= 3")
default:
    print("num < 4")
}

반복문

조건에 따라 실행되어야 하는 명령어를 조건문을 통해 분기하거나, 같거나 비슷한 명령을 반복할 때 반복문을 사용할 수 있다. 특히나 배열과 같은 시퀀스, 순서가 있는 데이터는 반복문으로 더욱 편리하게 처리할 수 있다.

스위프트의 반복문은 기존 프로그래밍 언어의 반복문과 크게 다르지 않다. 전통적인 C 스타일의 for 구문이 사라졌다는 점과 조건에 소괄호()를 생략할 수 있다는 점을 제외하고 말이다.

또한 do-while 구문은 스위프트에서 repeat-while 구문으로 구현되어 있다.

for-in 구문

for-in 반복 구문은 반복적인 데이터나 시퀀스를 다룰 때 많이 사용한다. 다른 언어에서의 for-each 구문과 유사하다.

for 루프 상수 in 시퀸스 아이템 {
    실행 코드
}

다음은 for-in 구문의 간단한 예시이다.
for i in 0...2 {
    print(i)
}
0
1
2

for i in 0...5 {
    if i.isMultiple(of: 2) {
        print(i)
        continue   // continue 키워드를 사용하면 바로 다음 시퀸스로
    }

    print("\(i) == 홀수")
}
0
1 == 홀수
2
3 == 홀수
4
5 == 홀수

let helloSwift: String = "Hello Swift!"

for char in helloSwift {
    print(char)
}
H
e
l
l
o
 
S
w
i
f
t
!

var result: Int = 1

// 시퀀스에 해당하는 값이 필요 없다면 와일드카드 식별자(_)를 사용
for _ in 1...3 {
    result *= 10
}

print("10의 3제곱은 \(result) 입니다.")
10의 3제곱은 1000 입니다.

for-in 구문은 스위프트의 기본 컬렉션 타입에서도 유용하게 사용할 수 있다.
// Dictionary
let friends: [String: Int] = ["Kim": 20, "Lee": 22, "Park": 21]

for tuple in friends {
    print(tuple)
}
(key: "Kim", value: 20)
(key: "Park", value: 21)
(key: "Lee", value: 22)
let address: [String: String] = ["도": "경기도", "시군구": "성남시 성남구", "동읍면": "성남동"]

for (key, value) in address {
    print("\(key) : \(value)")
}
동읍면 : 성남동
도 : 경기도
시군구 : 성남시 성남구
// Set
let areaCode: Set<String> = ["02", "031", "032", "033", "041", "042"]

for code in areaCode {
    print(code)
}
041
042
033
02
031
032

for-in 구문을 사용하여 반복 처리를 쉽게 할 수 있다.
하지만 스위프트에 더 익숙해지면 for-in 구문보다 map, filter, flatMap등을 더 많이 사용하게 될 것이다.

while 구문

while 반복 구문도 다른 프로그래밍 언어의 while 구문과 크게 다르지 않는다. 특정 조건(Bool 타입으로 지정되어야 한다.)이 성립하는 한 블록 내부의 코드를 반복해서 실행한다.

for-in 구문과 마찬가지로 continue, break 등의 키워드를 사용할 수 있다.

var names: [String] = ["Kim", "Lee", "Park"]

while !names.isEmpty {
    print("Good bye \(names.removeFirst())")
}
Good bye Kim
Good bye Lee
Good bye Park

repeat-while 구문

repeat-while 반복 구문은 다른 프로그래밍 언어의 do-while 구문과 크게 다르지 않다. repeat 블록의 코드를 먼저 실행한 후, while 다음의 조건이 성립하면 블록 내부의 코드를 반복 실행한다.

var names: [String] = ["Kim", "Lee", "Park"]

repeat {
    print("Good bye \(names.removeFirst())")
} while names.isEmpty == false
Good bye Kim
Good bye Lee
Good bye Park

구문 이름표

반복문을 작성하다 보면 종종 반복문을 중첩으로 작성하게 된다.
이때 반복문을 제어하는 키워드가 어떤 범위에 적용되어야 하는 지 애매하거나 큰 범위의 반복문을 종료하고 싶은데 작은 범위의 반복문만 종료되는 등 예상치 못한 실수를 할 수도 있다.

이러한 경우에는 반복문 앞에 이름과 함께 콜론을 붙여 구문의 이름을 지정해주면 좋다.이름이 지정된 구문을 제어하고자 할 때는 제어 키워드와 구문 이름을 함께 써주면 된다.

var numbers: [Int] = [3, 2342, 6, 3252]

numbersLoop: for num in numbers {
    if num > 5 || num < 1 {
        continue numbersLoop
    }

    var count: Int = 0

    printLoop: while true {
        print(num)
        count += 1

        if count == num {
            break printLoop
        }
    }

    removeLoop : while true {
        if numbers.first != num {
            break numbersLoop
        }
        numbers.removeFirst()
    }
}

print(numbers)
3
3
3
[2342, 6, 3252]
profile
나 애기 개발자 👶🏻

0개의 댓글