[swift 기초] 흐름 제어

silverCastle·2021년 8월 14일
0
post-thumbnail

C언와는 다르게 swift는 흐름 제어 구문에서 소괄호를 대부분 생략할 수 있다. 또한, 중괄호는 생략할 수 없다는 것이 특징이다.

💡 조건문

조건문에는 if문과 switch문이 있다. guard문도 있는데 추후에 설명할 예정이다.

✍️ if문

대표적인 조건문으로 if, else if, else 등의 키워드를 사용하여 구현할 수 있다. C언와는 다르게 if문의 조건 값이 반드시 Bool 타입이어야 한다는 것을 잊지 말자.

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문

C언어에서 switch문은 break를 사용하지 않으면 case를 연속으로 실행할 수 있었다. 하지만 swift에서 switch문은 break를 사용하지 않아도 case 내부에 있는 코드를 모두 실행하게 되면 switch 구문이 자동적으로 종료된다. 만약, case를 연속으로 실행하고 싶다면 fallthrough 키워드를 사용하면 된다.
비교될 값이 열거형 값처럼 뚜렷하게 한정적인 값이 아니라면 default를 꼭 작성해줘야 한다.

let number: Int = 5
switch number {
case 0:
    print("number == 0")
case 1...10:
    print("number == 1~10")
    // 다음 case도 실행하고 싶다면 fallthrough 키워드를 사용하자.
    fallthrough
case Int.min..<0, 101..<Int.max:
    print("number < 0 or number > 100")
    break
default:
    print("10 < number <= 100")
}

결과

number == 1~10
number < 0 or number > 100

만약, 지금처럼 비교될 값이 뚜렷하게 한정적인 값이 아닌 경우에 default를 작성하지 않는다면?
아래와 같이 오류를 내뱉게 된다.

Switch must be exhaustive

switch문의 입력 값으로 숫자 표현뿐만 아니라 문자, 문자열, 열거형, 튜플, 범위, 패턴이 적용된 타입 등 다양한 타입의 값도 사용할 수 있다.
아래는 튜플을 사용한 경우이다.

typealias NameAge = (name: String, age: Int)
let value: NameAge = ("silverCastle", 24)
switch value {
case ("silverCastle", 24):
    print("딩동댕!")
default:
    print("땡!")
}

결과

딩동댕!

튜플은 와일드카드 식별자를 함께 사용하면 더 유용하게 프로그래밍 할 수 있다.

typealias NameAge = (name: String, age: Int)
let value: NameAge = ("silverCastle", 24)
switch value {
case ("silverCastle", 10):
    print("딩동댕!")
case ("silverCastle", _):
    print("이름만 맞았습니다. 나이는 \(value.age)입니다.")
case (_, 24):
    print("나이만 맞았습니다. 이름은 \(value.name)입니다.")
default:
    print("땡!")
}

결과

이름만 맞았습니다. 나이는 24입니다.

하지만 와일드카드 식별자를 사용하면 무시된 값을 직접 가져와야 하는 불편함이 있기 때문에 let을 붙인 값 바인딩을 사용하여 이를 해결할 수 있다.

typealias NameAge = (name: String, age: Int)
let value: NameAge = ("silverCastle", 24)
switch value {
case ("silverCastle", 10):
    print("딩동댕!")
case ("silverCastle", let age):
    print("이름만 맞았습니다. 나이는 \(age)입니다.")
case (let name, 24):
    print("나이만 맞았습니다. 이름은 \(name)입니다.")
default:
    print("땡!")
}

결과

이름만 맞았습니다. 나이는 24입니다.

💡 반복문

같은 명령을 계속해서 반복한다고 가정할 때 반복문만큼 좋은 게 없을 것이다.

✍️ for-in문

C언어에서 사용하는 스타일의 for문(for(...;...;...))은 더 이상 사용하지 않는다. 자바에서 사용하는 for-each문과 유사하다고 보면 된다.

for i in 0...5 {
    print(i)
}

결과

0
1
2
3
4
5
let name: String = "silverCastle"
for char in name {
    print(char)
}

결과

s
i
l
v
e
r
C
a
s
t
l
e

✍️ while문

다른 프로그래밍 언어의 while문과 크게 다르지 않은데 조건 값이 반드시 Bool 타입이어야 한다는 것을 잊지 말자.

var friends: [String] = ["bronzeCastle", "silverCastle", "goldCastle"]
while friends.isEmpty == false {
    print("Hello, \(friends.removeFirst())")
}

결과

Hello, bronzeCastle
Hello, silverCastle
Hello, goldCastle

✍️ repeat-while문

C언어의 do-while문과 크게 다르지 않다. repeat 블록에 있는 코드를 1회 실행하고 while 조건이 성립하면 블록에 있는 코드를 반복 실행한다.

var friends: [String] = ["bronzeCastle", "silverCastle", "goldCastle"]
repeat {
    print("Hello, \(friends.removeFirst())")
}
while friends.isEmpty == false

결과

Hello, bronzeCastle
Hello, silverCastle
Hello, goldCastle

💡 구문 이름표

반복문을 사용하다가 종종 중첩 반복문을 사용할 때가 있다.
예를 들어, C언어에서 2개의 반복문이 중첩되어 있다고 가정하자. 현재 안에 있는 반복문에서 실행되고 있는데 안에 있는 반복문과 바깥에 있는 반복문 모두 탈출하고자 한다면 필자는 안에 있는 반복문에서 일종의 flag를 사용해서 반복문을 모두 탈출했던 경험이 있다.
하지만 반복문 앞에 이름과 함께 콜론을 붙여 구문의 이름을 지정해주는 구문 이름표를 사용한다면 이러한 번거러움을 없앨 수 있다.

firstLoop: while true {
    print("첫번째 반복문이에요.")
    secondLoop: while true {
        print("두번째 반복문이에요.")
        print("모든 반복문을 나가고 싶어요.")
        break firstLoop
    }
}

결과

첫번째 반복문이에요.
두번째 반복문이에요.
모든 반복문을 나가고 싶어요.

1개의 댓글

comment-user-thumbnail
2021년 8월 16일

유익한내용 감사합니다.

답글 달기