-
Chapter 3: Basic Control FlowRaywenderlich/Swift Apprentice 2021. 6. 16. 15:01
Version
Swift 5.5, iOS 15, Xcode 13
컴퓨터 프로그램(computer program)을 작성(writing)할 때, 다른 시나리오(scenarios)에서 수행할 작업을 컴퓨터에 알려야 할 필요가 있다. 예를 들어(for example), 계산기 앱(calculator app)에서 사용자(user)가 더하기(addition) 버튼(button)과 빼기(subtraction) 버튼(button)을 탭(taps)할 때 다른 작업을 수행해야 한다.
컴퓨터 프로그래밍(computer-programming) 용어(terms)에서 이 개념(concept)은 제어 흐름(control flow)으로 알려져 있는데, 프로그램(program)의 흐름(flow)이 다양한(various) 방법(methods)으로 제어(controlled)되기 때문이다. 이 장(chapter)에서는 구문(syntax)을 사용하여 흐름(flow)을 제어(control)함으로써, 프로그램(programs)에서 의사 결정(decisions)을 내리고 작업을 반복(repeat)하는 방법을 배운다. 또한 참(true)과 거짓(false)을 나타내는(represent) 부울(Booleans)과 이를 사용하여 데이터를 비교(compare)하는 방법에 대해서도 알아 본다.
Comparison operators
지금까지
Int
,Double
,String
과 같은 몇 가지 유형(types)을 살펴 보았다. 여기서는 비교 연산자(comparison operators)를 사용해 값(values)을 비교(compare)할 수 있는 또 다른 유형(type)에 대해 알아본다.둘 이상의 숫자 중 큰 것을 찾는 경우와 같이, 비교(comparison)를 수행(perform)할 때의 답은 참(true) 또는 거짓(false)이다. Swift에는 이를 위한 데이터 유형(type)이 있다.
Bool
이라 하는데 Boolean의 줄임말(short)로, 이는 참(true)과 거짓(false)이라는 개념(concept)을 중심으로 수학(mathematics)의 전체 분야(entire field)를 나타낸(invented) George Boole이라는 영리한(clever) 수학자의 이름에서 유래(after)했다.Swift에서 부울(Boolean)을 사용하는 방법은 다음과 같다:
let yes: Bool = true let no: Bool = false
그리고 Swift의 유형 추론(type inference) 덕분에 유형(type) 주석(annotation)을 생략(leave off)할 수 있다:
let yes = true let no = false
부울(Boolean)은
true
또는false
키워드(keywords)로 표시(denoted)되는 참(true) 또는 거짓(false)만 사용할 수 있다. 위의 코드에서 키워드(keywords)를 사용하여 각 상수(constant)의 상태(state)를 설정(set)한다.Boolean operators
부울(Booleans)은 일반적으로(commonly) 값(values)을 비교(compare)하는 데 사용된다. 예를 들어(for example), 두 개의 값(values)이 동일(true)한지 또는 그렇지 않은지(false) 알고 싶은 경우가 있다.
Swift에서는
==
로 표시(denoted)되는 등호 연산자(equality operator)를 사용하여 이 작업을 수행한다:let doesOneEqualTwo = (1 == 2)
Swift는
doOneEqualTwo
를Bool
로 추론(infers)한다. 분명하게(clearly), 1과 2는 같지 않으므로dosOneEqualTwo
는false
이다.마찬가지로(similarly)
!=
연산자(operator)를 사용하여 두 값(values)이 같지 않은지 확인할 수 있다:let doesOneNotEqualTwo = (1 != 2)
이번에는 1이 2와 같지 않기 때문에 비교(comparison)는 참(true)이며
dosOneNotEqualTwo
도true
가 된다.부정 연산자(not-operator)라고도 하는 접두사(prefix)
!
연산자(operator)는 true를 false로, false를 true로 전환(toggles)한다. 위 내용을 작성하는 또 다른 방법은 다음과 같다:let alsoTrue = !(1 == 2)
1은 2와 같지 않기 때문에
(1 == 2)
는false
이고!
는 그것을true
로 바꾼다(flips).두 개의 연산자(operators)를 더 사용하면, 해당 값(value)이 다른 값(value)보다 큰지(
>
) 아니면 작은지(<
) 확인(determine)할 수 있다. 수학(mathematics)에서의 배운 다음과 같은 연산들을 알고 있을 것이다:let isOneGreaterThanTwo = (1 > 2) let isOneLessThanTwo = (1 < 2)
그리고
isOneGreaterThanTwo
가false
이고,isOneLessThanTwo
이true
라는 것을 알아내는 것은 로켓 과학(rocket science)이 아니다.값(value)이 다른 값보다 작거나 같은지(less than or equal to) 확인(test)할 수 있는
<=
연산자(operator)도 있다.<
와==
의 조합(combination)이므로 첫 번째 값(value)이 두 번째 값(value)보다 작거나 같으면true
를 반환(return)한다.마찬가지로(similarly), 값(value)이 다른 값보다 크거나 같은지(greater than or equal to) 확인(test)할 수 있는
>=
연산자(operator)도 있다.Boolean logic
위의 각 예제(examples)는 하나의 조건(condition)만 확인(tests)한다. George Boole이 부울(Boolean)을 발명(invented)했을 때, 그는 이러한 초라한(humble) 시작(beginnings)보다 훨씬 더 많은 계획(planned)을 가지고 있었다. 그는 여러 조건(multiple conditions)을 결합(combine)하여 하나의 결과(result)를 생성(form)할 수 있는 부울(Boolean) 논리(logic)를 발명(invented)했다.
조건(conditions)을 결합(combine)하는 한 가지 방법은 AND를 사용하는 것이다. 두 개의 부울(Booleans)을 AND 하면 결과(result)는 또 다른 부울(Boolean)이다. 두 입력(input) 부울(Booleans)이 모두
true
이면 결과(result)는true
이다. 그렇지 않으면 결과(result)는false
이다.Swift에서 부울(Boolean) AND 연산자(operator)는
&&
이며 다음과 같이 사용한다:let and = true && true
이 경우(case),
and
는true
가 된다. 오른쪽의 값(values) 중 하나가false
이면and
는false
가 된다.조건(conditions)을 결합(combine)하는 또 다른 방법은 OR을 사용하는 것이다. 두 개의 부울(Booleans)을 OR할 때, 입력(input) 부울(Booleans) 중 하나가
true
이면 결과(result)는true
이다. 두 입력(input) 부울(Booleans) 모두가false
인 경우에만 결과(result)가false
가 된다.Swift에서 부울(Boolean) OR 연산자(operator)는
||
이며, 다음과 같이 사용한다:let or = true || false
이 경우(case),
or
는true
이다. 오른쪽에 있는 두 값(values)이 모두false
이면or
는false
가 된다. 둘 다true
라면or
는 여전히true
가 된다.Swift는 부울(boolean) 논리(logic)를 사용하여 여러(multiple) 조건(conditions)을 평가(evaluate)한다. 두 조건(conditions)이 참(true)인지 확인(determine)하고 싶은 경우에 AND를 사용한다. 두 조건(conditions) 중 하나 이상이 참(true)인지 관심 있다면 OR을 사용한다.
예를 들어(for example), 다음 코드를 고려(consider)해 본다:
let andTrue = 1 < 2 && 4 > 3 let andFalse = 1 < 2 && 3 > 4 let orTrue = 1 < 2 || 3 > 4 let orFalse = 1 == 2 || 3 == 4
이들 각각은 AND 또는 OR과 결합(combining)하여 두 개의 개별(separate) 조건(conditions)을 확인(tests)한다.
부울(Boolean) 논리(logic)를 사용하여 둘 이상의 비교(comparisons)를 결합(combine)하는 것도 가능(possible)하다. 예를 들어(for example), 다음과 같이 복잡한(complex) 비교(comparison)를 구성(form)할 수도 있다:
let andOr = (1 < 2 && 3 > 4) || 1 < 4
괄호(parentheses)는 표현(expression)을 명확(disambiguates)하게 한다. Swift는 괄호(parentheses) 안의 하위 표현식(sub-expression)을 먼저(first) 평가(evaluates)한 후, 다음 단계(steps)에 따라 전체(full) 표현식(expression)을 평가(evaluates)한다:
1. (1 < 2 && 3 > 4) || 1 < 4
2. (true && false) || true
3. false || true
4. trueString equality
때때로(sometimes) 두 문자열(strings)이 같은지(equal) 확인(determine)해야 하는 경우가 있다. 예를 들어(for example), 사진 속 동물의 이름을 맞추는 아동용 게임은 사용자(player)가 올바르게(correctly) 대답(answered)했는지 확인(determine)해야 한다.
Swift에서 표준(standard) 항등 연산자(equality operator)
==
를 사용하여 숫자(numbers)를 비교(compare)하는 것과 같은 방식으로 문자열(strings)을 비교(compare)할 수 있다. 예를 들면(for example) 다음과 같다:let guess = "dog" let dogEqualsCat = guess == "cat"
여기에서
"dog"
은"cat"
과 같지 않기 때문에dogEqualsCat
은 부울(Boolean) 값false
이다. 간단하다(simple).숫자와 마찬가지로(just as with numbers) 동일(equality) 비교(compare) 뿐만 아니라, 한 값(value)이 다른 값(value)보다 크거나(greater than) 작은지(less) 확인(determine)할 수도 있다. 예를 들면(for example) 다음과 같다:
let order = "cat" < "dog"
이 구문(syntax)은 해당 문자열(string)이 알파벳순(alphabetically)으로 다른 문자열 보다 앞서는지 확인(checks)한다. 이 경우(case)
"cat"
이"dog"
보다 앞서기(comes before) 때문에order
는true
이다.Note: 문자열(string) 동일성(equality)에 대한 자세한 내용은 9장(chapter), "Strings"에서 배우게 된다. 문자열(strings)에 특수 문자(special characters)가 포함(contain)되어 있을 때 나타나는(crop up) 몇 가지 흥미로운 점들(interesting things)을 확인하게 될 것이다.
Toggling a Bool
Bool
은 종종(often) "켜짐(on)" 또는 "꺼짐(off)" 상태(state)를 나타내기(represents)도 한다. 이러한 경우(cases), 상태(state) 간에 전환(toggled)될 수 있는 것이 일반적(common)이다. 예를 들어(for example), 앱(application)에서Bool
을 사용하여 조명 스위치(switch) 상태(state)를 나타내고(represent) "켜짐(on)"과 "꺼짐(off)" 으로 전환(toggle)할 수 있다.이러한 상황(situations)에서
Bool
을true
에서false
로 전환(flip)하고 다시 되돌리는(back again) 편리한(handy) 방법이 있다. 다음과 같다(like so):var switchState = true switchState.toggle() // switchState = false switchState.toggle() // switchState = true
여기서
switchState
라는 변수(variable)는true
로 시작(starts as)한다. 그리고 한 번toggle
하면false
가 된다. 또 한 번의toggle
후에는 다시true
로 설정(set to)된다.Note: 여기에서
toggle()
은 함수(function) 호출(call)이다. 이에 대한 자세한 내용은 5장(chapter), "Functions" 그리고 특정 유형(types)에 적용(apply to)하는 방법은 12장(chapter), "Methods"에서 확인할 수 있다.Mini-exercises
myAge
라는 상수(constant)를 만들고 나이(age)를 설정한다. 그런 다음 부울(Boolean) 논리(logic)를 사용하여 나이(age)가 13세에서 19세 사이의 사람인지 확인(determine)하는isTeenager
라는 상수(constant)를 만든다.theirAge
라는 또 다른 상수(constant)를 만들고, 30으로 설정한다. 그런 다음 부울(Boolean) 논리(logic)를 사용하여 둘 모두가 10대인지 확인(determine)하는bothTeenagers
라는 상수(constant)를 만든다.reader
라는 상수(constant)를 만들고, 당신의 이름을 문자열(string)로 설정한다.author
라는 상수(constant)를 만들고, Matt Galloway로 설정한다. 그리고 문자열을 비교하여reader
와author
가 같은지(equal) 확인(determine)하는authorIsReader
상수(constant)를 만든다.- 문자열 비교(string comparison)를 사용하여
reader
가author
보다 알파벳 순서상 앞서는지 판별(determine)하는readerBeforeAuthor
상수(constant)를 만든다.
The if statement
프로그램(program)의 흐름(flow)을 제어(controlling)하는 가장 일반적(common)인 첫 번째(first) 방법은 특정 조건(certain condition)이 참(true)인 경우에만 프로그램(program)이 무언가를 수행할 수 있도록 하는
if
문(statement)을 사용하는 것이다. 예를 들어(for example), 다음을 고려(consider)해 본다:if 2 > 1 { print("Yes, 2 is greater than 1.") }
이것은 간단한
if
문(statement)이다. 조건(condition)이 참(true)이면 중괄호(braces) 사이의 코드를 실행(execute)하고 조건(condition)이 거짓(false)이면 중괄호(braces) 사이의 코드를 실행(execute)하지 않는다. 이게 전부이다(it’s as simple as that).if
문(statement)의 핵심은 조건(condition)이다. 조건(condition)은 확인(checked) 하고자 하는 것이며, 중괄호(braces) 안의 코드는 실행되거나 실행되지 않는다. 따라서if
문(statement)은 조건문(conditional statement)의 한 형태이다. 이 장(chapter)에서 해당 용어(term)가 다시 나타나는 것을 볼 수 있을 것이다.if
문을 확장(statement)하여, 조건(condition)이 거짓(false)인 경우 실행할 코드를 제공(provide)할 수 있다. 이를 else 절(clause)이라 하며, 다음은 그 예(example)이다:let animal = "Fox" if animal == "Cat" || animal == "Dog" { print("Animal is a house pet.") } else { print("Animal is not a house pet.") }
여기서
animal
이"Cat"
또는"Dog"
와 같으면(equals), 첫 번째 코드 블록(block)을 실행(run)한다.animal
이"Cat"
또는"Dog"
와 같지 않으면if
문(statement)의else
부분 블록(block)을 실행(run)하여 디버그 영역(debug area)에 다음을 출력(printing)한다:Animal is not a house pet.
그러나
if
문(statements)을 더 다양하게 사용할 수 있다(you can go even further). 때로는(sometimes) 하나의 조건(condition)을 확인(check)한 다음, 다른 조건을 확인해야 할 수 있다. 이때 이전(previous)if
문(statement)의else
절(clause)에 다른if
문(statement)을 중첩(nesting)하는else-if
를 사용할 수 있다.다음과 같이 사용할 수 있다:
let hourOfDay = 12 var timeOfDay = "" if hourOfDay < 6 { timeOfDay = "Early morning" } else if hourOfDay < 12 { timeOfDay = "Morning" } else if hourOfDay < 17 { timeOfDay = "Afternoon" } else if hourOfDay < 20 { timeOfDay = "Evening" } else if hourOfDay < 24 { timeOfDay = "Late evening" } else { timeOfDay = "INVALID HOUR!" } print(timeOfDay)
이러한 중첩(nested)
if
문(statements)은 참(true) 조건(condition)을 찾을 때까지 여러 조건(multiple conditions)을 하나씩 확인(test)한다. 다음(subsequent)else-if
조건(conditions)이 참(true)인지 여부에 관계없이(regardless of) 첫 번째 참(true) 조건(condition)과 연결된(associated with) 코드만 실행(executed)한다. 다시 말해(in other words), 조건(conditions)의 순서(order)가 중요하다.조건(conditions)이 참(true)이 아닌 경우(case)를 처리(handle)하기 위해 끝(end)에
else
절(clause)을 추가(add)할 수 있다. 이else
절(clause)은 선택 사항(optional)이다. 이 예제(example)에서는timeOfDay
가 출력될 때 유효한 값(valid value)을 보장(ensure)하기 위해 필요하다.이 예제(example)에서
if
문(statement)은 하루 중의 시간을 나타내는(representing) 숫자(number)를 가져와, 해당 시간 범위를 나타내는(representing) 문자열(string)로 변환(converts)한다. 24시간(24-hour clock)을 사용하여 한 번에 하나씩 순서(order)대로 확인(checked)한다:- 첫 번째로 해당 시간이 6시 미만(less than)인지 확인(check)한다. 참이라면, 이른 아침(early morning)임을 의미한다.
- 해당 시간이 6보다 작지(less than) 않은 경우, 첫 번째 else-if로 계속 진행(continues)하여 12보다 작은지(less than) 확인(checks)한다.
- 그런 다음(then) 조건(conditions)이 거짓(false)으로 판명(turn)되면, 해당 시간이 17 미만(less than), 20 미만(less than), 24 미만(less than)인지 확인(checks)한다.
- 마지막으로(finally), 범위를 벗어나면(out of range) 해당 정보(information)를 콘솔(console)에 출력(prints)한다.
위의 코드에서
hourOfDay
상수(constant)는12
이다. 따라서 해당 코드는 다음을 출력(print)한다:Afternoon
hourOfDay < 20
과hourOfDay < 24
조건(conditions)도 모두 참(true)이지만, 조건(condition)이 참(true)인 첫 번째 블록(first block)만 실행(executes)된다. 이 경우(case)에는hourOfDay < 17
조건(condition) 블록(block)이다.Short-circuiting
if
문(statements)에 대한 중요한 사실(important fact)은 AND(&&
) 또는 OR(||
)로 구분된(separated by) 여러(multiple) 부울(Boolean) 조건(conditions)에서 발생(happens)한다.다음 코드를 고려(consider)해 본다:
if 1 > 2 && name == "Matt Galloway" { // ... }
if
문(statement)의 첫 번째 조건(condition)인1 > 2
는false
이다. 그러므로(therefore) 전체 표현(whole expression)은 결코true
가 될 수 없다.따라서 Swift는 표현식(expression)의 두 번째 부분(second part) 즉(namely),
name
을 확인(check)하지 않는다. 마찬가지로(similarly), 다음 코드를 고려(consider)해 본다:if 1 < 2 || name == "Matt Galloway" { // ... }
1 < 2
가true
이므로name
의 값(value)에 관계없이 전체 표현식(whole expression)이true
이어야 한다. 따라서(therefore), 다시 한 번name
확인(check)을 수행(executed)하지 않는다. 이것은 나중에 더 복잡한 데이터 유형(complex data types)을 다룰 때(dealing with) 유용(handy)할 것이다.Encapsulating variables
if
문(statements)은 중괄호(braces)를 사용하여 변수(variables)를 캡슐화(encapsulate)하는 새로운 개념(concept)의 scope를 도입(introduce)한다. 고객(client)에게 청구할 요금(fee)를 계산(calculate)한다고 할때, 거래(deal) 내용은 다음과 같다:최대 40시간까지는 시간당 $25, 그 이후에는 시간당 $50를 받는다(You earn $25 for every hour up to 40 hours, and $50 for every hour after that).
Swift를 사용하면 다음과 같이 요금(fee)을 계산(calculate)할 수 있다:
var hoursWorked = 45 var price = 0 if hoursWorked > 40 { let hoursOver40 = hoursWorked - 40 price += hoursOver40 * 50 hoursWorked -= hoursOver40 } price += hoursWorked * 25 print(price)
이 코드는 시간(hours)을 가져와 40을 초과(over)하는지 확인(checks)한다. 참이라면, 40을 초과하는 시간을 계산(calculates)하고 $50를 곱해(multiplies) 그 결과를
price
에 추가한다. 그런 다음hoursWorked
에서 40시간을 초과하는 시간을 빼고(subtracts) $25를 곱(multiplies)하여 총(total)price
에 추가(adds)한다.위의 예제(example)에서 결과(result)는 다음과 같다:
1250
여기서 흥미로운 점(interesting thing)은
if
문(statement) 내부(inside)의 코드이다. 40이 넘는 시간을 저장(store)하기 위해 새로운 상수(constant)hoursOver40
을 선언(declaration)했다. 분명하게(clearly),if
문(statement) 내부(inside)에서 사용할 수 있다. 그러나 위 코드의 마지막(at the end)에서 이를 사용(use)하려고 하면 어떻게 되는지 확인해 본다:... print(price) print(hoursOver40)
그러면 다음과 같은 오류(error)가 발생한다:
Use of unresolved identifier 'hoursOver40'
이 오류(error)는 생성된(created) 범위(scope) 내에서만
hoursOver40
상수(constant)를 사용할 수 있음을 알려(informs)준다. 이 경우(case)에서는if
문(statement)에 새로운 범위(scope)가 도입(introduced)되었으므로, 해당 범위가 끝나면(finished) 이 상수(constant)를 더 이상 사용할 수 없다.그러나 각 범위(scope)는 상위 범위(parent scope)의 변수(variables)와 상수(constants)를 사용할 수 있다. 위의 예(example)에서,
if
문(statement)의 범위(scope)는 상위 범위(parent scope)에서 생성한price
와hoursWorked
변수(variables)를 사용한다.The ternary conditional operator
이제 2장(chapter) "Types & Operations"에서 볼 수 없었던 새로운 연산자(operator)를 소개(introduce)한다. 삼항 조건 연산자(ternary conditional operator)라고 하며
if
문(statements)과 관련(related to)이 있다.두 변수(variables)의 최소값(minimum)과 최대값(maximum)을 알아낼(determine) 때, 다음과 같이
if
문(statements)을 사용할 수 있다:let a = 5 let b = 10 let min: Int if a < b { min = a } else { min = b } let max: Int if a > b { max = a } else { max = b }
지금이라면 이것이 어떻게 작동하는지 알겠지만, 코드의 양이 많다. 삼항 조건 연산자(ternary conditional operator)를 사용해 이를 몇 줄(a couple of lines)로 줄일(shrink) 수 있다.
삼항 조건 연산자(ternary conditional operator)는 조건(condition)의 참(true) 거짓(false) 여부에 따라(depending on) 두 값(values) 중 하나를 반환(returns)한다. 문법(syntax)은 다음과 같다:
(<CONDITION>) ? <TRUE VALUE> : <FALSE VALUE>
이 연산자(operator)를 사용하면 위의 긴 코드 블록(code block)을 다음과 같이 다시 쓸(rewrite) 수 있다:
let a = 5 let b = 10 let min = a < b ? a : b let max = a > b ? a : b
첫 번째 예(example)에서 조건(condition)은
a < b
이다. 이것이 참(true)이면min
에 할당(assigned)되는 결과(result)는a
의 값(value)이 되고, 거짓(false)이면b
의 값(value)이 된다.훨씬 간단(simpler)하다는 데에 동의(agree)할 것이다. 자주(regularly) 사용하게 될 유용한(useful) 연산자(operator)이다.
Note: 두 숫자 중 크거나(greater) 작은(smaller) 숫자를 찾는(finding) 것은 매우 일반적(common)인 작업(operation)이기 때문에, Swift 표준 라이브러리(standard library)는 이러한 목적(purpose)의
max
와min
두 가지 함수(functions)를 제공(provides)한다. 이 책의 앞부분(earlier)에서 주의를 기울였다면(paying attention) 이미 학습했던 내용임을 기억(recall)할 것이다.Mini-exercises
myAge
상수(constant)를 생성하고 나이에 맞게 초기화(initialize)한다.if
문(statement)을 작성하여 나이가 13세에서 19세 사이라면Teenager
를 출력(print out)하고, 13세에서 19세 사이가 아니면Not a Teenager
를 출력한다.answer
상수(constant)를 생성하고 삼항 조건(ternary condition)을 사용하여 위의 예제(exercise)와 동일한 경우에 대해 출력 결과를 동일하게 설정(set)한다. 그런 다음answer
을 출력(print out)한다.
Loops
반복문(loops)은 Swift가 코드를 여러 번 실행(executing)하는 방법이다. 이 섹션(section)에서는 반복문(loop)의 한 유형(type)인
while
반복문(loop)에 대해 배운다. 다른 프로그래밍 언어(programming language)를 알고 있다면 개념(concepts)과 구문(syntax)에 익숙(familiar)할 것이다.While loops
while 반복문(loop)은 조건(condition)이 참(true)인 동안 코드 블록(block)을 반복(repeats)한다. 다음과 같은 방식으로
while
반복문(loop)을 만든다:while <CONDITION> { <LOOP CODE> }
반복문(loop)은 모든 반복(iteration)에 대한 조건(condition)을 확인(checks)한다. 조건(condition)이
true
이면 반복문(loop)이 실행(executes)되고, 다른 반복(iteration)으로 이동(moves)한다. 조건(condition)이false
이면 반복문(loop)이 중지된다.if
문(statements)과 마찬가지로while
반복문(loops)에도 범위(scope)가 있다.가장 간단한(the simplest)
while
반복문(loop)은 다음과 같은 형식(form)이다:while true { }
조건(condition)이 항상
true
이기 때문에 이while
반복문(loop)은 절대로 끝나지 않는다. 물론(of course), 프로그램(program)이 영원히 동작(spin)할 것이기 때문에 이러한while
반복문(loop)을 작성하지는 않을 것이다. 이 상황(situation)을 무한 루프(infinite loop)라고 하며, 프로그램이 중단(crash)되지는 않지만 컴퓨터가 정지(freeze)할 수 있다.다음은
while
반복문(loop)의 더 유용한(useful) 예(example)이다:var sum = 1 while sum < 1000 { sum = sum + (sum + 1) }
이 코드는 값(value)이
1000
보다 커지는(greater than) 지점까지 수학적 순서(mathematical sequence)를 계산(calculates)한다.반복문(loop)은 다음과 같이 실행(executes)된다:
- Before iteration 1:
sum
= 1, loop condition = true - After iteration 1:
sum
= 3, loop condition = true - After iteration 2:
sum
= 7, loop condition = true - After iteration 3:
sum
= 15, loop condition = true - After iteration 4:
sum
= 31, loop condition = true - After iteration 5:
sum
= 63, loop condition = true - After iteration 6:
sum
= 127, loop condition = true - After iteration 7:
sum
= 255, loop condition = true - After iteration 8:
sum
= 511, loop condition = true - After iteration 9:
sum
= 1023, loop condition = false
아홉 번의 반복(iteration) 후,
sum
변수(variable)는1023
이 되므로sum < 1000
의 반복(loop) 조건(condition)은 거짓(false)이 된다. 이 시점에서(at this point) 반복(loop)은 중지된다.Repeat-while loops
while
반복문(loop)의 변형(variant)을 repeat-while 반복문(loop)이라 한다. 조건(condition)이 처음(beginning)이 아니라 반복문(loop)의 끝(end)에서 평가(evaluated)된다는 점이while
반복문(loop)과 다르다. 다음과 같이repeat-while
반복문(loop)을 구성(construct)한다:repeat { <LOOP CODE> } while <CONDITION>
다음은 지난 섹션(section)과 동일하지만
repeat-while
반복문(loop)을 사용하는 예(example)이다:sum = 1 repeat { sum = sum + (sum + 1) } while sum < 1000
이 예제(example)의 결과(outcome)는 이전(before)과 동일하다. 그러나(however), 항상 그런 것은 아니다. 다른 조건(different condition)에서는 다른 결과(different result)가 나올 수 있다.
다음
while
반복(loop)을 고려(consider)해 본다:sum = 1 while sum < 1 { sum = sum + (sum + 1) }
동일한 조건(condition)을 사용하는
repeat-while
반복문(loop)은 다음과 같다:sum = 1 repeat { sum = sum + (sum + 1) } while sum < 1
일반
while
반복문(loop)의 경우 조건(condition)sum < 1
은 처음부터(from the start)false
이다. 즉, 반복문(loop)의 본문(body)에 도달(reached)하지 않는다. 반복문(loop)이 반복(iterations)을 실행(execute)하지 않으므로sum
의 값(value)은1
이 된다.repeat-while
반복문(loop)의 경우, 반복(loop)이 한 번 실행(executes)되기 때문에sum
은3
이 된다.Breaking out of a loop
때로는(sometimes), 반복문(loop)에서 일찍(early) 벗어나고(break out) 싶을 때가 있다. 반복문(loop)의 실행(execution)을 즉시(immediately) 중지하고, 반복문(loop) 이후의 코드를 계속(continues) 실행하는
break
문(statement)을 사용하여 이를 수행할 수 있다.예를 들어(for example), 다음 코드를 고려(consider)해 본다:
sum = 1 while true { sum = sum + (sum + 1) if sum >= 1000 { break } }
여기서 반복문(loop) 조건(condition)은
true
이므로, 반복문(loop)은 일반적으로(normally) 영원히 반복(iterate)된다. 그러나(however),break
는sum
이1000
이상(greater than or equal to)이면while
반복문(loop)을 종료시킨다.동일한 반복문(loop)을 다양한 방법으로 작성하여, 컴퓨터 프로그래밍(computer programming)에서 여러 가지 방법으로 동일한 결과(result)를 얻을(achieve) 수 있다는 것을 알게 되었다.
가장 읽기(read) 쉽고 최대한 의도(intent)를 잘 전달(conveys)할 수 있는 방법(method)을 선택해야 한다. 이는 충분한(enough) 시간과 연습(practice)으로 내면화(internalize)할 수 있다.
Mini-exercises
counter
라는 변수(variable)를 만들고0
으로 설정(set)한다.counter is X
(여기서X
를counter
값(value)으로 대체(replaced with)한다)를 출력(prints out)하는 조건(condition)counter < 10
으로 while 반복문(loop)을 만든 다음counter
를1
씩 증가(increments)시킨다.counter
라는 변수(variable)를 만들고0
으로 설정(set)한다.roll
이라는 다른 변수(variable)를 만들고0
으로 설정(set)한다.repeat-while
반복문(loop)를 만들고, 반복문(loop) 내부에서roll
을0
에서5
사이의 임의(random)의 숫자를 선택(pick)하는Int.random(in: 0...5
)로 설정(set)한다. 그런 다음counter
를1
씩 증가(increment) 시킨다. 마지막으로(finally)After X rolls, roll is Y
(여기서X
는counter
값(value)이고Y
는roll
값(value)이다)을 출력(print)한다. 첫 번째(first)0이
굴려 졌을(rolled)때 반복문(loop)이 완료(finishes)되도록 반복(loop) 조건(condition)을 설정(set)한다.
Challenges
다음으로 넘어가기(moving on) 전에 기본 제어 흐름(basic control flow)에 대한 지식(knowledge)을 확인(test)하는 몇 가지 챌린지(challenges)가 있다. 스스로 해결(solve)해 보려고 하는 것이 가장 좋지만, 막힌다면(get stuck) 다운로드(download)나 소스 코드 링크(source code link)에서 해답(solutions)을 참고할 수 있다.
Challenge 1: Find the error
다음 코드의 문제점을 확인해 본다.
let firstName = "Matt" if firstName == "Matt" { let lastName = "Galloway" } else if firstName == "Ray" { let lastName = "Wenderlich" } let fullName = firstName + " " + lastName
Challenge 2: Boolean challenge
다음 각 구문(statements)에서 부울(Boolean)
answer
상수(constant)의 값(value)을 확인해 본다.let answer = true && true let answer = false || false let answer = (true && 1 != 2) || (4 > 3 && 100 < 1) let answer = ((10 / 2) > 3) && ((10 % 2) == 0)
Challenge 3: Snakes and ladders
위치(position) 1에서 위치(position) 20으로 이동하는 뱀과 사다리(snakes & ladders) 게임(game)을 하고 있다고 상상(imagine)해 본다. 위치(position) 3과 위치(position) 7에 사다리(ladders)가 있어 각각(respectively) 15와 12로 이동한다. 그리고 위치(position) 11과 17(position)에 뱀(snakes)이 있어, 각각(respectively) 2와 9로 이동한다.
1과 20 사이의 원하는 위치(position)로 설정할 수 있는
currentPosition
상수(constant)를 생성한다. 그리고 원하는 주사위 굴림(roll of the dice)으로 설정(set)할 수 있는diceRoll
상수(constant)를 생성한다. 마지막으로(finally) 사다리(ladders)와 뱀(snakes)을 고려하여 최종 위치(position)를 계산(calculate)하는nextPosition
을 생성한다.Challenge 4: Number of days in a month
월(month, 모두 소문자(lowercase)
String
으로 표시)과 현재 연도(year,Int
로 표시)가 주어지면, 해당 월(month)의 일(days) 수를 계산(calculate)합니다. 연도(year)가 4의 배수(multiple)이지만 100의 배수(multiple)가 아닌 경우 "2월(february)"은 윤년(leap years)이 되어 29일이라는 것을 기억(remember)해야 한다. 또한 연도(year)가 400의 배수(multiple)인 경우에도 2월(february)은 29일이다.Challenge 5: Next power of two
숫자(number)가 주어지면 그 숫자보다 크거나 같은(above or equal to) 2의 다음 거듭제곱(power of two)을 계산(determine)한다.
Challenge 6: Triangular number
숫자(number)가 주어지면 해당 깊이(depth)의 삼각수(triangular number)를 출력(print)한다. 다음 링크에서 삼각수(triangular numbers)의 정의를 확인할 수 있다:
https://en.wikipedia.org/wiki/Triangular_number
Challenge 7: Fibonacci
n번째 피보나치 수(Fibonacci number)를 계산(calculate)한다. 피보나치 수(Fibonacci numbers)는 1과 1로 시작하고, 다음(subsequent) 숫자(numbers)는 시퀀스(sequence)에서 이전의 두 값(values)을 더한 것과 같다. 다음 링크에서 피보나치 수(Fibonacci numbers)의 정의를 확인할 수 있다:
https://en.wikipedia.org/wiki/Fibonacci_number
Challenge 8: Make a loop
반복문(loop)을 사용하여 주어진 인수(factor)의 최대 12까지의 시간표(times table)를 출력(print out)한다.
Challenge 9: Dice roll table
2개의 6면체 주사위 굴림(six-sided dice rolls)이 주어졌을 때 2에서 12까지의 각 숫자를 만드는 조합(combinations)의 수를 보여주는 표(table)를 출력한다. 공식(formula)을 사용하지 않고, 가능한 각 주사위 굴림(dice roll)을 고려(considering)하여 조합(combinations)의 수를 남김없이(exhaustively) 계산(compute)해야 한다.
Key points
- 부울(Boolean) 데이터 유형(type)
Bool
을 사용하여 참(true)과 거짓(false)을 나타낸다(represent). - 부울(Boolean)을 반환(return)하는 비교 연산자(comparison operators)는 다음과 같다:
- 부울(Boolean) 논리(
&&
,||
)를 사용하여 비교(comparison) 조건(conditions)을 결합(combine)할 수 있다. - 조건(condition)에 따라(based on) 간단한 결정(decisions)을 내리기 위해
if
문(statements)을 사용한다. - 단일 조건(single condition) 이상(beyond)으로 의사 결정(decision)을 확장(extend)하기 위해,
if
문(statement) 내에서else
와else-if
를 사용한다. - short-circuiting은 부울(Boolean) 표현식(expression)의 최소한(minimal)의 필수 부분(required parts)만 평가(evaluated)되도록 한다.
- 간단한
if
문(statements) 대신 삼항 연산자(ternary operator,a ? b : c
)를 사용할 수 있다. - 변수(variables)와 상수(constants)는 특정(certain) 범위(scope)에 속하며, 그 범위를 넘어서(beyond)는 사용할 수 없다. 범위(scope)는 상위(parent)의 변수(variables)와 상수(constants)를 상속(inherits)한다.
while
반복문(loops)을 사용하면, 조건(condition)이 충족(met)될 때까지(until) 특정(certain) 작업(task)을 여러 번 수행(perform)할 수 있다.repeat
반복문(loops)은 항상 반복(loop)을 한 번 이상 실행(execute)한다.break
문(statement)을 사용하면 반복문(loop)에서 벗어날(break out) 수 있다.
'Raywenderlich > Swift Apprentice' 카테고리의 다른 글
Chapter 6: Optionals (0) 2021.10.08 Chapter 5: Functions (0) 2021.09.02 Chapter 4: Advanced Control Flow (0) 2021.08.03 Chapter 2: Types & Operations (0) 2021.03.16 Chapter 1: Expressions, Variables & Constants (0) 2021.01.19