-
Chapter 1: Expressions, Variables & ConstantsRaywenderlich/Swift Apprentice 2021. 1. 19. 20:04
Version
Swift 5.5, iOS 15, Xcode 13
이 첫 번째 장(chapter)에서는 몇 가지 기본 사항(basics)을 살펴본다. 먼저 코드 작동 방식(how code works)을 배운다. 그런 다음 Swift 코드를 작성하는 데 사용할 도구(tools)에 대해 배운다.
그런 다음 코드 주석(code comments), 산술 연산(arithmetic operations), 상수 및 변수(constants and variables)와 같은 몇 가지 기본 사항(basics)을 학습하여 Swift 로의 모험(adventure)을 시작한다. 이는 모든 언어의 기본(fundamental) 구성 요소들(building blocks) 중 일부이며, Swift도 다르지 않다.
우선(first of all), 컴퓨터의 기본 작동 방식(basic workings)을 다룰 것이다. 프로그래밍(programming)의 더 복잡한 측면(aspects)으로 들어가기 전에 기초를 배우는 것이 실제로 도움이 되기(really pays) 때문이다.
How a computer works
믿지 못할 수도 있지만, 컴퓨터는 그 자체는 그리 똑똑하지 않다. 컴퓨터 능력(power)의 대부분은 개발자의 프로그래밍(programmed) 방식에서 비롯된다. 컴퓨터의 성능을 제대로(successfully) 활용하려면, 컴퓨터의 작동 방식(work)을 이해하는 것이 중요하다.
컴퓨터 자체는 단순한 기계(simple machines)라는 사실을 알게 된다면 놀랄(surprise)지도 모른다. 컴퓨터의 중심(heart of)에는 중앙 처리 장치(Central Processing Unit , CPU)가 있다. 이는 본질적으로(essentially) 수학 기계로, 숫자에 대한 덧셈(addition), 뺄샘(subtraction) 및 기타 산술 연산(arithmetical operations)을 수행(performs)한다. 컴퓨터가 작동(operate)할 때 보이는 모든 것은 CPU가 초당 수백만 번(millions of times per second) 처리(crunching)하는 숫자를 기반으로 한다.
CPU는 레지스터(registers)라고 하는 작은 메모리 장치(memory units)에 처리하는 숫자를 저장(stores)한다. CPU는 RAM(Random Access Memory)이라고 하는 컴퓨터의 주 메모리(main memory)에서 레지스터(registers)로 숫자를 읽거나(read), 레지스터(register)에 저장된(stored in) 숫자를 RAM에 다시 쓸(write) 수 있다. 이로 CPU는 레지스터 뱅크(bank of registers)에 모두 들어가지 않는 대량의 데이터(large amounts of data)를 처리할 수 있다.
작동 방식(works)에 대한 도표(diagram)는 다음과 같다:
CPU가 RAM의 값(values)을 레지스터(registers)로 가져 오면(pulls), 해당 값(values)을 연산 장치(math unit)에서 사용하고 그 결과를 다른 레지스터(register)에 다시 저장(stores)한다.
CPU가 덧셈(addition), 뺄셈(subtraction), RAM에서 읽기(read) 또는 RAM에 쓰기(write)를 수행할 때마다 단일(single) 명령(instruction)을 실행(executing)한다. 각 컴퓨터 프로그램(program)은 수천에서 수백만 개의 간단한 명령(simple instructions)을 실행하여 작업을 수행(running)한다. 운영 체제(operating system), macOS와 같은 복잡한 컴퓨터 프로그램(complex computer program)은 수백만 개의 명령(instructions)으로 구성(consists of)되어 있다.
컴퓨터에 수행할 작업을 지시하는 개별 명령(individual instructions)을 작성하는 것은 전적으로 가능(entirely possible)하지만, 가장 단순한 프로그램(the simplest programs)을 제외한 모든 경우에 시간이 많이 걸리고(immensely time-consuming) 지루(tedious)할 것이다. 이는 대부분의 컴퓨터 프로그램(most computer programs)이 단순한 수학 이상의 인터넷 검색(surf the Internet), 이미지 조작(manipulate images), 그리고 친구와 채팅(chat) 등을 목표로하기 때문이다.
개별 명령(individual instructions)을 작성(writing)하는 대신 특정(specific) 프로그래밍 언어(programming language), 여기서는 Swift로 소스 코드(source code, 또는 code)를 작성(writing)한다. 이 코드는 컴파일러(compiler)라는 컴퓨터 프로그램(computer program)으로 입력(put through)되어, CPU가 실행(execute)하는 방법을 알고 있는 작은 기계 명령어(small machine instructions)로 변환(converts)한다. 작성한 코드의 각 행(line)을 많은 명령(instructions)으로 바꾸며, 일부 행(lines)은 수십 개의 명령(instructions)이 될 수도 있다.
Representing numbers
알다시피 숫자(number)는 컴퓨터가 하는 모든 작업의 기본(bread and butter)이 되는 요소이다. 컴파일러(compiler)에 보내는 어떤 정보(information)든 결국(eventually) 숫자가 된다. 예를 들어(for example), 텍스트(text) 블록(block) 내의 각 문자(character)는 숫자(number)로 표시된다(represented). 이에 대한 자세한 내용은 텍스트 블록(block of text)의 컴퓨터 용어(computer term)인 문자열(strings)을 포함한 유형(types)을 다루는 2장(chapter), “Types & Operations”에서 자세히 알아볼 것이다.
이미지(images)도 예외(exception)가 아니다. 컴퓨터(computer)에서 각 이미지(image)는 일련의 숫자(series of numbers)로도 표시(represented)된다. 이미지(image)는 픽셀(pixels)이라고 하는 수천 또는 수백만 개의 요소(elements)로 분할(split into)되며, 각 픽셀(pixel)은 단색(solid color)이다. 픽셀(pixels)이 엄청나게 작은 고해상도 화면(particularly high-resolution display)을 사용하지 않는다면, 컴퓨터(computer) 화면(screen)을 자세히 확인해(look closely) 이 블록들(blocks)을 볼 수 있다(make out). 이러한 단색 픽셀(solid color pixels) 각각은 일반적으로 세 개의 숫자로 표시(represented)되며, 빨간색(red)의 양, 녹색(green)의 양, 파란색(blue)의 양이다. 예를 들어 완전히 빨간 픽셀(entirely red pixel)은 100% 빨간색(red), 0% 녹색(green), 0% 파란색(blue)이다.
CPU가 사용하는 숫자(numbers)는 익숙한 숫자와 현저하게(notably) 다르다. 일상 생활(day-to-day life)에서 숫자(numbers)를 다룰(deal with) 때는 10진법(base 10, decimal system)를 사용한다. 이 숫자 시스템(numerical system)을 오랫동안 사용해 왔으므로 어떻게 작동하는지 직관적으로(intuitively) 이해하고 있다. CPU의 관점(point of view)을 이해할 수 있도록 기본 10의 작동 방식을 고려(appreciate)해 본다.
10진수 숫자 423에는 3개의 단위(units), 2개의 10(two tens)과 4개의 100(four hundreds)이 포함(contains)되어 있다:
10진법 시스템(base 10 system)에서 숫자의 각 자릿수(digit)는 0, 1, 2, 3, 4, 5, 6, 7, 8, 9의 값(value)을 가질 수 있으며, 각 자릿수(digit)에 대해 총(total) 10개의 가능한 값(possible values)을 제공하기 때문에 10진법(base 10)이라 한다. 그러나 각 자릿수(digit)의 실제 값(true value)은 숫자(number)의 위치에 따라(depends on) 달라진다. 오른쪽에서 왼쪽으로 이동하면, 각 자릿수(digit)에 10의 거듭 제곱(power)이 곱해진다(multiplied). 따라서 가장 오른쪽 위치(far-right position)의 승수(multiplier)는 10의 0의 거듭 제곱(power)인 1이다. 왼쪽으로 이동하면 다음 승수(multiplier)는 1의 거듭 제곱(power)인 10이 된다. 다시 왼쪽으로 이동하면 다음 승수(multiplier)는 10의 2제곱(power)인 100이다. 이런 식으로 계속된다(and so on).
즉, 각 자릿수(digit)는 해당 자리의 오른쪽 숫자의 10배 값(value)이다. 숫자 423은 다음과 같다:
(0 * 1000) + (4 * 100) + (2 * 10) + (3 * 1) = 423
Binary numbers
10진법(base 10)이 익숙하기 때문에, 숫자를 읽는 방법에 대해 생각할 필요가 없다. 매우 자연스럽게(natural) 느껴진다. 하지만 컴퓨터에게 10진법(base 10)은 너무 복잡하다. 컴퓨터는 단순(simple-minded)하다. 2진법(base 2)으로 작업하는 것을 좋아한다.
2진법(base 2)은 종종 바이너리(binary)라고도 하며, 이전에 들어 봤을 것이다. 2진법(base 2)에는 각 자릿수(digit)에 대해 0 또는 1의 두 가지 옵션(options)만 있다.
물리적 수준(physical level)에서 각 자릿수(digit)에 대해 두 가지 옵션(options)만 처리(handle)하는 것이 가장 쉽기 때문에 대부분(almost all)의 최신 컴퓨터는 바이너리(binary)를 사용한다. 대부분 컴퓨터를 구성(comprises)하는 디지털 전자 회로(digital electronic circuitry)에서 전압(electrical voltage)이 존재(presence)하면 1이고, 존재하지 않는다면(absence) 0이다. 이것이 2진법(base 2)이다.
Note: 2개가 아닌 3개의 가능한 값(possible values)을 가지는 삼항 숫자 시스템(ternary numeral system)을 사용하는 실제(real) 컴퓨터와 가상(imagined) 컴퓨터가 있다. 컴퓨터 과학자(computer scientists), 엔지니어(engineers), 전담 해커(dedicated hackers)는 3진법 컴퓨터(base-3 computer)의 가능성을 계속해서 탐구(explore)하고 있다. https://en.wikipedia.org/wiki/Ternary_computer 및 http://hackaday.com/tag/ternary-computer/를 참고한다.
다음은 2진수(base 2) 1101의 표현(representation)이다:
10진법(base 10) 체계(number system)에서 자릿값(place values)은 1, 10, 100, 1000 등으로 10배씩 증가(increase)한다. 2진법(base 2)에서는 1, 2, 4, 8, 16 등으로 2배씩 증가(increase)한다. 일반적인 규칙(general rule)은 오른쪽에서 왼쪽으로 이동할 때 기본 숫자(base number, 이 경우에는 2)의 거듭 제곱(powers)으로 각 자릿수(digit)를 곱하는 것이다.
따라서 맨 오른쪽 숫자(far-right digit)는 (1 * 2^0), 즉 (1 * 1), 1을 나타낸다(represents). 왼쪽의 다음 숫자(digit)는 (0 * 2^1), 즉 (0 * 2), 0을 나타낸다(represents). 위의 삽화(illustration)에서 블록(blocks) 위에 있는 2의 거듭 제곱(powers)을 확인할 수 있다.
다시 말해(put another way), 2의 모든 거듭 제곱(power)은 존재하는 (1) 이거나 존재하지 않는 (0)의 이진수(binary number) 구성 요소(component)이다. 이진수(binary number)의 10진수(decimal) 버전(version)은 해당 숫자(number)를 구성(make up)하는 2의 모든 거듭 제곱(powers)의 합(sum)이다. 따라서 이진수(binary number) 1101은 다음과 같다:
(1 * 8) + (1 * 4) + (0 * 2) + (1 * 1) = 13
10진법(base 10 number) 423을 이진수(binary)로 변환(convert)하려면, 423을 2의 거듭 제곱(powers) 구성 요소(component)로 나누기(break down)만 하면 된다. 다음과 같다:
(1 * 256) + (1 * 128) + (0 * 64) + (1 * 32) + (0 * 16) + (0 * 8) + (1 * 4) + (1 * 2) + (1 * 1) = 423
위의 방정식(equation)에서 이진 자리수(binary digits)를 살펴보면(scanning) 알 수 있듯이, 결과 이진수는 110100111이다. 수학(math)을 해보면 이것이 423과 같다는 것을 스스로 증명(prove)할 수 있다.
이진수의 각 자릿수(digit of a binary number)에 대한 컴퓨터 용어(computer term)는 "binary digit"의 축약(contraction)인 비트(bit)이다. 8비트(bits)는 1바이트(byte)를 구성(make up)한다. 4비트(bits)는 니블(nibble)이라고 하며, 오래된 컴퓨터 과학자들(old-school computer scientists)도 유머 감각(sense of humor)이 있다는 것을 보여주는 단어 유희이다.
컴퓨터의 제한된 메모리(limited memory)는 일반적으로(normally) 특정 길이(certain length)까지의 숫자를 처리(deal with)할 수 있음을 의미한다. 예를 들어(for example) 각 레지스터(register)는 일반적으로 32비트(bits) 또는 64비트(bits)이므로, 32비트(bit) 및 64비트(bit) CPU라 말한다.
따라서(therefore) 32 비트(bit) CPU는 최대 10진수(maximum base-number) 4,294,967,295개를 처리(handle)할 수 있다. 이는 이진수(base 2 number)로
11111111111111111111111111111111
, 32개이다.컴퓨터(computer)는 CPU 최대 값(maximum)보다 큰 숫자를 처리(handle)할 수 있지만, 해당 계산(calculations)은 학교에서 수행한 긴 곱셈(multiplication)과 같이 특별(special)하고 긴(longer) 방식으로 분할(be split up)해서 관리(managed)해야 한다.
Hexadecimal numbers
상상(imagine)할 수 있듯이, 이진수(binary numbers)로 작업하는 것은 작성(write)하거나 입력(type)하는데 긴 시간이 걸릴 수 있기 때문에 매우 지루(tedious)할 수 있다. 이러한 이유로 컴퓨터 프로그래밍(computer programming)에서 종종 16진수(hexadecimal, 줄여서 hex)로 알려진 다른 숫자 형식(number format)을 사용한다. 이것은 16진법(base 16)이다.
물론(of course) 16개의 고유한(distinct) 숫자(numbers)는 없다. 단지 0부터 9까지 10개만 있다. 이를 보완(supplement)하기 위해 a부터 f까지 처음 6개의 문자(letters)를 사용한다.
이러한 값은 다음과 같은 십진수(decimal numbers)와 동일하다:
a
=10
b
=11
c
=12
d
=13
e
=14
f
=15
다음은 이전과 동일한 형식(format)을 사용하는 16진법(base 16)의 예이다:
먼저 16진수 숫자(hexadecimal numbers)를 단어(words)처럼 보이게 만들 수 있다. 그것에 약간의 재미를 느낄 수도 있을 것이다.
이제 각 자릿수(digit)의 값(values)은 16의 거듭 제곱(powers)을 나타낸다. 이전과 동일한 방식으로 이 숫자(number)를 다음과 같이 10진수(decimal)로 변환(convert)할 수 있다:
(12 * 4096) + (0 * 256) + (13 * 16) + (14 * 1) = 49374
문자(letters)를 해당(equivalents) 십진수(decimal)로 변환(translate)한 다음, 일반적인 계산(calculations)을 수행(perform)한다.
16진수(hexadecimal)는 각 16진수 숫자(hexadecimal digit)를 정확히(precisely) 4개의 2진수(binary digits)로 나타낼(represent) 수 있기 때문에 유용하다. 이진수(binary number)
1111
은 16진수(hexadecimal)f
와 같다(equivalent). 따라서 각 16진수 자릿수(hexadecimal digit)를 나타내는(representing) 2진수(binary digits)를 간단히 연결하여 2진수(binary) 또는 10진수(decimal)보다 짧은 16진수(hexadecimal number)를 만들 수 있다.예를 들어(for example), 위의 숫자
c0de
를 고려해 본다:c = 1100 0 = 0000 d = 1101 e = 1110 c0de = 1100 0000 1101 1110
이것은 컴퓨터(computers)가 긴 32비트(bit) 또는 64비트(bit) 이진수(binary numbers)를 사용하는 방식을 고려할 때 오히려 도움이 된다. 십진수(decimal)에서 가장 긴 32비트(bit) 숫자는 4,294,967,295이다. 16진수(hexadecimal)에서는
ffffffff
이다. 훨씬 더 간결(compact)하고 명확(clear)하다.How code works
컴퓨터(computers)에는 많은 제약(constraints)이 있으며, 그 자체(themselves)로는 아주 작은 수의 일만 할 수 있다. 컴퓨터 프로그래머(computer programmer)가 코딩(coding)으로 추가하는 것은 이 작은 것들을 올바른 순서(right order)로 모아 훨씬 더 큰 것을 생산(produce)하는 것이다.
코딩(coding)은 레시피(recipe)를 작성(writing)하는 것과 매우 유사하다. 재료(ingredients, 데이터)를 조립(assemble)하고, 사용 방법에 대한 단계별(step-by-step) 레시피(recipe)를 컴퓨터(computer)에 제공한다.
예(example)를 들면 다음과 같다:
Step 1. Load photo from the hard drive. Step 2. Resize photo to 400 pixels wide by 300 pixels high. Step 3. Apply sepia filter to photo. Step 4. Print photo.
이런 단계(step)의 집합(set)을 의사 코드(pseudo-code)라 한다. 유효한(valid) 컴퓨터 프로그래밍 언어(computer programming language)로 작성되지는 않았지만, 사용하려는 알고리즘(algorithm)을 나타낸다(represents). 이 경우 알고리즘(algorithm)은 사진을 찍고 크기를 조정한 다음 필터를 적용하여 출력한다. 비교적 간단한(straightforward) 알고리즘(algorithm)이지만, 그럼에도 불구하고(nonetheless) 알고리즘(algorithm)이다.
Swift 코드는 이와 같이 컴퓨터(computer)에 대한 단계별(step-by-step) 지침(instructions) 목록(list)이다. 이 지침(instructions)은 이 책을 읽으면서 더 복잡(complex)해지겠지만, 컴퓨터(computer)에게 한 번에 한 단계(step)씩 수행할 작업을 지시하는 원칙(principle)은 동일하다.
각 프로그래밍 언어(programming language)는 이러한 단계(steps)를 표현(expressing)하는 높은 수준(high-level)의 사전 정의(pre-defined)된 방법이다. 컴파일러(compiler)는 작성한 코드를 해석(interpret)하여 CPU가 실행(execute)할 수 있는 명령어(instructions)로 변환(convert into)하는 방법을 알고 있다.
다양한 프로그래밍 언어(programming languages)가 있으며, 각각 고유한 장점(advantages)과 단점(disadvantages)이 있다. Swift는 매우(extremely) 현대적인(modern) 언어(language)dl다. 다른 많은 언어(languages)의 강점(strengths)을 통합(incorporates)하면서 동시에 약점(weaknesses)의 일부를 해결(ironing)한다. 앞으로 몇 년이 지나면 프로그래머(programmers)는 Swift를 오래(old)되고 딱딱(crusty)한 것으로 되돌아 볼 수도 있다. 하지만 현재로서는 계속 개선(improve)되고 발전(evolve)하고 있다.
컴퓨터 하드웨어(computer hardware), 숫자 표현(number representation), 코드(code), 그리고 이것들이 모두 함께 작동하여 어떻게 최신 프로그램(modern program)을 만드는 지에 대한 간략한 둘러보기(brief tour)였다. 한 섹션(section)에서 다루기(cover)에는 내용이 너무 많았다. 이제 Swift로 코드를 작성(write)하는 데 사용하는 도구(tools)에 대해 알아볼 시간이다.
Playgrounds
소프트웨어(software)를 작성(write)하는 데 사용하는 도구 집합(set of tools)을 툴 체인(toolchain)이라고 한다. 코드를 작성(write)하는 툴 체인(toolchain)의 일부를 통합 개발 환경(IDE, Integrated Development Environment)이라고 한다. 가장 일반적으로(commonly) 사용하는 Swift 용 IDE는 Xcode라고 하며, 이를 사용할 것이다.
Xcode에는 플레이 그라운드(playground)라는 편리한(handy) 문서(document) 유형(type)이 포함(includes)되어 있어, 완전한(complete) 앱(app)을 빌드(building)하지 않고도 코드를 빠르게(quickly) 작성(write)하고 테스트(test)할 수 있다. 책 전체에서 플레이 그라운드(playgrounds)를 사용하여 코딩을 연습하므로, 작동 방식을 이해(understand)하는 것이 중요(important)하다. 이 장(chapter)의 나머지(rest) 부분에서 이러한 내용을 배우게 될 것이다.
Creating a playground
플레이 그라운드(playground)를 시작하려면, File ▸ New ▸ Playground를 클릭(click)한다. Xcode는 다음과 같은 템플릿(templates)을 제공(present)한다:
선택한 플랫폼(platform)은 Xcode가 플레이 그라운드(playground)를 만드는 데 사용할 템플릿(template) 버전(version)을 정의(defines)한다. 현재(currently) 옵션(options)은 iOS, macOS이다. 각 플랫폼(platform)에는 자체(own) 환경(environment)이 설정(set up)되어 있으며, 코드를 사용할 수 있도록 준비(ready for)된다.
원하는 플랫폼(platform)을 선택한다. 플랫폼에 따른 코드(platform-specific code)를 작성하지 않고, Swift 언어(language)의 핵심 원칙(core principles)을 배우게 된다.
Blank 템플릿(template)을 선택(select)하고 Next을 클릭(click)한다. Xcode는 플레이 그라운드(playground)의 이름을 지정하고 저장(save)할 위치(location)를 선택(select)하도록 요청(ask)한다.
이름은 단지(merely) 겉치레(cosmetic)로 사용하기 위한 용도이다. 플레이 그라운드(playgrounds)를 생성할 때, 무엇에 관한 것인지 기억(remember)하는 데 도움이 되는 이름을 자유롭게 선택한다. 예를 들어(for example), 1장(chapter), “Expressions, Variables & Constants”에서 작업하는 플레이 그라운드(playground) 이름을 Chapter1로 지정할 수 있다.
Create를 클릭(click)하여 플레이 그라운드(playground)를 만들고 저장한다. Xcode는 다음과 같은 플레이 그라운드(playground)를 제공(presents)한다:
빈(blank) 플레이 그라운드(playgrounds)라도 비어있는(empty) 상태가 아니라, 몇 가지 기본 시작 코드가 있다. 곧, 이 코드의 의미를 알게 될 것이므로 걱정(worry)할 것 없다.
Playgrounds overview
언뜻 보기에 플레이 그라운드(playground)는 다소 화려한(fancy) 텍스트 편집기(text editor)처럼 보일 수 있다. 본질적으로 바로 그것이다.
이 스크린샷(screenshot)은 알아야 할 첫 번째이자 가장 중요한 사항을 강조(highlights)한다:
- Source editor: Swift 코드를 작성(write)하는 영역(area)이다. Notepad이나 TextEdit 같은 텍스트 편집기(text editor)와 매우 유사하다. 모든 문자(characters)가 동일한 너비(width)인 고정 폭 글꼴(monospaced font)을 사용하는 것을 알 수 있다. 이렇게하면 코드를 읽고(read) 구성(format)하는 것이 훨씬 쉬워진다.
- Results sidebar: 이 영역(area)에는 코드의 결과가 표시된다. 책을 읽으면서 코드가 실행(executes)되는 방식에 대해 자세히 알아 본다. 이곳은 코드가 예상(expected)대로 작동하는지 확인(confirm)하는 주요 장소(main place)이다.
- Resources tree: 플레이그라운드(playground)에 포함(contained)된 리소스(resources) 목록을 보여준다. 여기에서 기본(main) 플레이그라운드(playground) 파일(file)부터 시작해서 추가 소스(additional sources)와 리소스(resources)를 포함한 플레이그라운드(playground)에 대한 전체 리소스 트리(resources tree)를 확인 수 있습니다. 이를 사용해 소스(sources)를 여러(multiple) 파일로 분할(split)하는 매우 복잡한(complex) 플레이그라운드(playgrounds)를 구축할 수 있다.
- Execution control: 이 컨트롤(control)을 사용하면 전체(entire) 플레이 그라운드(playground) 파일(file)을 실행(run)하거나, 상태(state)를 지워 다시 실행(run)할 수 있다. 기본적(default)으로, 플레이 그라운드(playgrounds)는 자동(automatically)으로 실행(execute)되지 않는다. 이 설정을 길게 누르고 "Automatically Run"을 선택(selecting)하면 모든 변경 사항(change)이 실행(execute)되도록 변경(change)할 수 있다.
- Activity viewer: 플레이 그라운드(playground)의 상태(status)를 보여준다. 스크린샷(screenshot)에서는 플레이 그라운드(playground)가 실행(executing)을 완료(finished)했고, 소스 편집기(source editor)에서 더 많은 코드를 처리(handle)할 준비가 되었음을 보여준다. 플레이 그라운드(playground)가 실행(executing) 중일 때, 이 뷰어(viewer)는 스피너(spinner)로 이를 표시(indicate)한다.
- Left panel control: 리소스 트리(resources tree)가 있는 왼쪽 패널(left panel)을 토글(toggles)한다. 지금은 닫아 둔다.
- Right panel control: 오른쪽 패널(right panel)을 토글(toggles)한다. 여기에서 열려(open)있는 소스 파일(source file)에 대한 정보(information)를 찾을 수 있다. 일반적으로 이를 닫아둔다.
- Bottom panel control: 하단 패널(bottom panel)을 토글(toggles)한다. 여기에서 실행 중(running)인 플레이 그라운드(playground)의 출력(output)을 볼 수 있다. 나중에 보게 될 것이다.
Xcode ▸ Preferences… ▸ Text Editing ▸ Line Numbers를 클릭(clicking)하여 소스 편집기(source editor)의 왼쪽에 행 번호(line numbers)를 켤 수 있다. 행 번호(line numbers)는 코드의 일부(parts)를 참조(refer to)할 때 매우 유용 할 수 있다.
플레이 그라운드(playgrounds)는 소스 편집기(source editor)의 코드를 위에서 아래로(from top to bottom) 실행(execute)한다. 커서(cursor)를 그 위로 이동하면 실행 버튼(play button)이 각 줄 옆에 표시(floats)되며, 파일의 시작 부분부터 클릭(click)한 줄(line)까지 실행(run)할 수 있다. 강제(force) 재실행(re-execution)하려면 Execution control 버튼(button)을 두 번 클릭하여, 한 번은 중지(stop)하여 지우고(clear) 다시 클릭하여 실행(rerun)한다.
플레이 그라운드(playground) 실행(execution)이 완료(finished)되면, Xcode는 results sidebar를 업데이트(updates)하여 소스 편집기(source editor)에 해당 행(corresponding line)의 결과(results)를 표시한다. 이 책의 예제(examples)를 작업하면서, 코드의 결과를 해석(interpret)하는 방법을 알아본다.
Note: 특정 조건(certain conditions)에서 Xcode가 행 기반 실행(line-based execution)을 잘못(incorrectly) 비활성화(disables)할 수 있다. 이 경우, execution control 버튼(button)을 사용하여 전체(entire) 플레이 그라운드(playground)를 실행(run)한다.
Getting started with Swift
이제 컴퓨터(computers)가 어떻게 작동하는지, "플레이 그라운드(playground)"가 무엇인지 알았으니 이제 Swift를 작성(writing)할 차례이다.
자신만의 플레이 그라운드(playground)를 작성해 따라갈 수 있다. 간단하게 생성하고 코드를 입력한다.
먼저(first up), 코드를 구성(organize)하는 데 도움이 되는 다음 것들을 확인해 본다.
Code comments
Swift 컴파일러(compiler)는 소스 코드(source code)에서 실행 가능한(executable) 코드를 생성(generates)한다. 이를 위해 이 책에서 배우게 될 세부 규칙들(detailed set of rules)을 사용한다. 때때로(sometimes), 이러한 세부 사항(details)은 코드를 특정 방식으로 작성(wrote)한 이유 또는 해결(solving)중인 문제(problem)에 대한 큰 그림(big picture)을 모호(obscure)하게 만들 수 있다. 이를 방지(prevent)하려면 다음 사람이 작업 내용을 이해할 수 있도록 작성한 내용을 문서화(document)하는 것이 좋다. 그 다음 사람은 미래의 당신일 수도 있다.
Swift는 대부분의 다른 프로그래밍 언어(programming languages)와 마찬가지로 주석(comments)을 사용하여 코드를 문서화(document)할 수 있다. 이를 사용해 코드와 나란하게(alongside) 직접(directly) 텍스트(text)를 작성(write)할 수 있으며, 컴파일러(compiler)는 이를 무시(ignored)한다.
주석(comment)을 작성하는 첫 번째 방법은 다음과 같다:
// This is a comment. It is not executed.
이것은 한 줄 주석(single line comment)이다.
단락(paragraphs)을 작성하도록 다음과 같이 쌓을(stack) 수 있다:
// This is also a comment. // Over multiple lines.
그러나 다음과 같이 여러 줄(multiple lines)에 걸친 주석(comments)을 작성(write)하는 더 좋은 방법이 있다:
/* This is also a comment. Over many.. many... many lines. */
여러 줄 주석(multi-line comment)의 시작은 간단하게
/*
로, 끝은*/
로 표시한다.Swift를 사용하면 다음과 같이 주석(comments)을 중첩(nest)할 수도 있다:
/* This is a comment. /* And inside it is another comment. */ Back to the first. */
이것은 특별히 흥미(interesting)로워 보이지는 않지만, 다른 프로그래밍 언어(programming languages)를 사용해 본 적이 있다면 다를 수 있다. 첫 번째
*/
에서 주석(comment)을 닫는다(closing)고 생각하기 때문에, 이와 같이 주석(comments)을 중첩(nest)하는 것을 허용하지 않는 프로그래밍 언어도 있다. 코드를 문서화(document)하거나 이유(reasoning)를 설명(explain)하거나 단순히(simply) 동료(colleagues)에게 농담(jokes)을 남기기 위해, 필요한 경우 코드 주석(comments)을 사용한다.Printing out
코드가 수행(doing)하는 작업의 결과(results)를 확인하는 것도 유용하다. Swift에서는
print
명령(command)을 사용하여 이를 수행(achieve)할 수 있다.print
는 디버그 영역(debug area, 콘솔이라고도 함)에 원하는 항목을 출력(output)한다.예를 들어(for example), 다음 코드를 고려(consider)해 본다:
print("Hello, Swift Apprentice reader!")
그러면 디버그 영역(debug area)에 다음과 같은 멋진 메시지(message)가 출력(output)된다:
위 사진에서 빨간색 상자로 강조 표시된(highlighted) 버튼(button)을 사용하여 디버그 영역(debug area)을 숨기거나(hide) 표시(show)할 수 있다. View ▸ Debug Area ▸ Show Debug Area 을 클릭(click)하여 동일한 작업을 수행할 수도 있다.
Arithmetic operations
하나 이상의 데이터를 가져 와서 다른 데이터로 바꾸는 것(turn into)을 연산(operation)이라고 한다.
연산(operations)을 이해(understand)하는 가장 간단한 방법은 산술(arithmetic)을 생각해 보는 것이다. 덧셈 연산(addition operation)은 두 숫자를 합으로 변환(converts)한다. 뺄셈 연산(subtraction operation)은 두 숫자를 차로 변환(converts)한다.
앱(apps) 전체에서 간단한 산술(arithmetic)을 찾을 수 있다. 게시물(post)의 "좋아요" 수를 집계(tallying)하는 것부터 버튼(button)이나 창(window)의 올바른 크기(correct size)와 위치(position)를 계산(calculating)하는 것까지 숫자(numbers)는 어디에나(everywhere) 있다.
이 섹션(section)에서는 Swift가 제공(offer)하는 숫자(numbers)에 적용(apply to)되는 다양한(various) 산술 연산(arithmetic operations)에 대해 알아 본다. 이후 장(chapters)에서는 숫자(numbers) 이외의 유형(types)에 대한 연산(operations)을 볼 수 있다.
Simple operations
Swift의 모든 연산(operations)은 연산자(operator)라는 기호(symbol)를 사용하여 수행(perform)하는 작업(operation) 유형(type)을 나타낸다(denote). 덧셈(addition), 뺄셈(subtraction), 곱셈(multiplication), 나눗셈(division) 등 초등학교(early school days)에서 배운 네 가지 산술 연산(arithmetic operations)을 생각해(consider) 본다. 이러한 간단한 연산(operations)을 위해 Swift는 다음과 같은 연산자(operators)를 사용한다:
- 덧셈(add):
+
- 뺄셈(Subtract):
-
- 곱셈(Multiply):
*
- 나눗셈(Divide):
/
이러한 연산자(operators)는 다음과 같이 사용된다:
2 + 6 10 - 2 2 * 4 24 / 3
이러한 각 행(lines)은 표현식(expression)이며, 이는 각각에 값(value)이 있음을 의미한다. 이 경우 네 가지 표현식(expressions)은 모두 같은 값인 8을 나타낸다. 펜(pen)과 종이(paper)에 연산(operations)을 작성(write)하는 방법과 코드가 어떻게 유사한지 확인해 본다. 이것을 플레이 그라운드(playground)에 바로(straight into) 입력(enter)할 수 있다.
하늘색(light blue)의 줄 번호(line numbers)는 아직 실행(run)되지 않은 것이다. 코드를 실행(run)하려면 커서(cursor) 옆의 마지막 줄(last line)에 있는 하늘색(light blue) 시작(play) 버튼(button)을 클릭(click)한다.
실행(running)하면 플레이 그라운드(playground)는 실행(run)된 행(lines)에서 파란색 사이드 바(sidebar)를 제거(removes)한다. results sidebar라고 하는 오른쪽 표시 줄(right-hand bar)에서 이러한 표현식(expressions)의 값(values)을 볼 수 있다.
원한다면, 연산자(operator)를 둘러싼(surrounding) 공백(whitespace)을 제거(remove)할 수 있다:
2+6
이렇게 변경하면 파란색 사이드 바(sidebar)가 다시 실행(rerun)해야 하는 행(lines)을 나타낸다(indicate). 파란색 화살표(blue arrow)를 클릭(clicking)하거나, Shift-Enter 단축키(shortcut)를 사용하여 다시 실행(run)할 수 있다.
Note: Shift-Enter는 현재 커서(current cursor)까지의 모든 구문(statements)을 실행(runs)하고 다음 행(line)으로 이동(advances)한다. 이렇게 Shift-Enter를 계속 누르면서 전체(whole) 플레이 그라운드(playground)를 단계별(step-by-step)로 쉽게 실행(run)할 수 있으며, 이는 기억을 몸에 새기는(muscle memory) 훌륭한 단축키(shortcut)이다.
공백(whitespace)을 제거(removing)하는 것은 전부(all)이거나 전무(nothing)이며, 방식(styles)을 혼용(mix)할 수 없다. 예를 들면(for example):
2+6 // OK 2 + 6 // OK 2 +6 // ERROR 2+ 6 // ERROR
첫 번째 오류(error)는 다음과 같다:
Consecutive statements on a line must be separated by ';'
두 번째 오류(error)는 다음과 같이 표시된다:
'+' is not a postfix unary operator
지금은 이러한 오류 메시지(error messages)를 이해할 필요가 없다. 연산자(operator) 양쪽(both sides)에 공백(whitespace)이 있거나 없어야 한다.
양쪽에 공백(whitespace)이 있으면 읽기가 더 쉬울 때가 많다.
Decimal numbers
위의 모든 연산(operations)에서의 숫(numbers)자는 정수(integers)를 사용했다. 그러나 알다시피 모든 숫자가 정수인 것은 아니다.
예를 들어 다음을 고려해 본다:
22 / 7
이 결과가 3이라는 것을 알게 된다면 놀랄(surprised)수도 있다. 표현식(expression)에서 정수(integers)만 사용하면, Swift는 결과(integer)도 정수로 만든다. 이 경우 결과는 정수(integer)로 반올림(rounded down)된다.
다음과 같이 변경하여 Swift가 소수(decimal numbers)를 사용하도록 할 수 있다:
22.0 / 7.0
이번에는 예상(expected)대로 결과가 3.142857142857143 이다.
The remainder operation
지금까지 본 네 가지 연산(operations)은 평생 동안(most of your life) 해왔기 때문에 이해하기 쉽다. Swift에서는 더 복잡한(complex) 연산(operations)을 사용할 수 있다. 모두 표준 수학 연산(standard mathematical operations)이며 덜 일반(common)적인 연산일 뿐이다. 이제 이를 확인해 본다(let’s turn to them now).
이들 중 첫 번째는 나머지(remainder) 연산(operation)으로, 모듈로 연산(modulo operation)이라고도 한다. 나눗셈(division)에서 분모(denominator)와 몫을 곱하고 나머지(remainder)를 더하면 분자가 된다. 이 나머지(remainder)가 정확히 나머지 연산(remainder operation)이 제공하는 것이다. 예를 들어(for example), 10 모듈로(modulo) 3은 1과 같다(equals). 3은 10에 세 번 들어가고, 나머지(remainder)는 1이기 때문이다.
Swift에서 나머지 연산자(remainder operator)는 % 기호(symbol)이며, 다음과 같이 사용한다:
28 % 10
이 경우의 결과는
8
이다. 10은 28에 두 번 들어가고, 나머지는 8이 되기 때문이다. 소수(decimal numbers)를 사용하여 동일한 계산(compute)을 하려면 다음과 같아야 한다:(28.0).truncatingRemainder(dividingBy: 10.0)
이는 28을 10으로 나눈(divided) 다음 결과(result)를 자르고(truncates), 여분의 소수(extra decimals)를 잘라내어(chopping off) 나머지(remainder)를 반환한다. 소수(decimals)가 없는 경우 결과(result)는 %와 동일(identical)하다.
Shift operations
왼쪽 쉬프트(shift left) 및 오른쪽 쉬프트(shift right) 연산(operations)은 10 진수의 이진형(binary form)을 취하고, 숫자를 각각 왼쪽 또는 오른쪽으로 이동(shift)한다. 그런 다음 새로운 이진수(binary number)의 10 진수 형식(decimal form)을 반환(return)한다.
예를 들어(for example), 십진수(decimal number) 14를 8자리 이진수로 패딩(padded)하면
00001110
이다. 이 숫자를 두 자리 왼쪽으로 이동(shifting)하면,00111000
이 되고 십진수(decimal)로 56이 된다.다음은 이 이동(shift) 연산(operation) 중에 발생하는 동작에 대한 설명(illustration)이다:
오른쪽의 빈 자리(empty)를 채우기 위해 들어오는 숫자(digits)는
0
이 된다. 왼쪽 끝에서 떨어지(fall off)는 숫자(digits)는 소실 된다(lost). 오른쪽 이동(shifting right)은 동일하지만 숫자가 오른쪽으로 이동한다.이 두 연산(operations)의 연산자(operators)는 다음과 같다:
- 왼쪽 이동(Shift left):
<<
- 오른쪽 이동(Shift right):
>>
이는 두 개 이상의 문자(character)가 포함(contain)된 첫 번째 연산자(operators)이다. 실제로(in fact) 연산자(operators)는 원하는 수의 문자(characters)를 포함(contain)할 수 있다.
다음은 두 연산자(operators)를 모두 사용하는 예(example)이다:
1 << 3 32 >> 2
이 두 값(values)은 숫자 8과 같다.
시프트(shifts)를 사용하는 한 가지 이유는 2의 거듭 제곱(powers)을 쉽게 곱(multiplying)하거나 나누기(dividing) 위해서이다. 왼쪽으로 1 이동(shifting)하는 것은 2를 곱(multiplying)하는 것과 같고, 왼쪽으로 2 이동(shifting)하는 것은 4를 곱(multiplying)하는 것과 같다.
마찬가지로(likewise) 오른쪽으로 1 이동(shifting)하는 것은 2로 나누는(dividing) 것과 같고, 오른쪽으로 2 이동(shifting)하는 것은 4로 나누는(dividing) 것과 같다.
예전에는(in the old days), CPU에서 복잡한(complex) 곱셈(multiplication)과 나눗셈(division) 연산(arithmetic)보다 비트 이동(shifting bits)이 훨씬 간단하기 때문에 코드에서 이 트릭(trick)을 자주 사용했다. 따라서(therefore) 시프트(shifting)를 사용하면 코드가 더 빨라진다.
그러나(however), 요즘(these days)의 CPU는 훨씬 빠르며, 컴파일러(compilers)는 곱셈(multiplication)과 나눗셈(division)을 2의 거듭 제곱(powers)의 시프트(shifts)로 변환(convert)할 수도 있다. 따라서 2진수를 사용(binary twiddling)하는 경우에서만 시프트(shifting)을 보게 될 것이다. 임베디드 시스템(embedded systems) 프로그래머(programmer)가 아니라면 아마 볼 수 없을 것이다.
Order of operations
물론(of course) 값(value)을 계산(calculate)할 때, 여러(multiple) 연산자(operators)를 사용할 수 있다. 다음은 Swift에서 이를 수행하는 방법의 예(example)이다:
((8000 / (5 * 10)) - 32) >> (29 % 5)
Swift에서 괄호(parentheses)는 두 가지 목적(purposes)으로 사용된다. 자신을 포함한 코드를 읽는 모든 사람에게 의미하는 바를 명확하게하고, 모호함(disambiguate)을 없애기 위한 것이다. 예를 들어(for example), 다음을 고려(consider)해 본다:
350 / 5 + 2
이 결과는 72 (350 나누기(divided) 5, 더하기(plus) 2) 또는 50 (350 나누기(divided) 7) 중 하나의 값일 것이다. 학교에서 배운대로라면 "72"가 될 것이다.
Swift는 동일한 추론(reasoning)을 사용하며 연산자 우선 순위(operator precedence)로 이를 달성(achieves)한다. 나눗셈 연산자(division operator,
/
)는 덧셈 연산자(addition operator,+
)보다 우선 순위(precedence)가 높으므로, 이 예제(example)에서는 코드는 나눗셈 연산(division operation)을 먼저 실행(executes)한다.50을 반환(return)하기 위해 Swift가 먼저 덧셈(addition) 연산을 하기 원한다면, 다음과 같이 괄호(parentheses)를 사용할 수 있다:
350 / (5 + 2)
우선 순위(precedence) 규칙(rules)은 학교에서 배운 수학과 동일(math)하다. 곱셈(multiply)와 나눗셈(divide)은 동일한 우선 순위(precedence)이며, 덧셈(add)과 뺄셈(subtract)보다 높은 우선 순위(precedence)를 가진다.
Math functions
또한 Swift에는 필요할 때 사용할 수 있는 광범위한(vast range) 수학 함수(functions)가 있다. 특히(especially) Swift의 전문가로 복잡한(complex) 게임을 작성할 때 삼각법(trigonometry)을 사용(pull out)해야 할 수도 있다.
Note: 이 모든 함수(functions)가 Swift의 일부인 것은 아니다. 운영 체제(operating system)는 일부만을 제공(provides)한다. 플레이 그라운드(playground) 템플릿(template)의 일부로 제공되는 import 구문(statement)을 제거해선 안된다. 해당 구문이 없다면 Xcode는 이러한 함수(functions)를 찾을 수 없다고 할 것이다.
예를 들어(for example), 다음을 고려(consider)해 본다:
sin(45 * Double.pi / 180) // 0.7071067811865475 cos(135 * Double.pi / 180) // -0.7071067811865475
각도(angle)를 각(degrees)에서 호도(radians)로 변환(convert)한 다음 각각(respectively) 사인(sine)과 코사인(cosine)을 계산(compute)한다. 둘 다 Swift가 제공(provides)하는
Double.pi
정수(constant)를 사용하여 컴퓨터에서 가능한 한 정밀(precision)한 파이(pi)를 어떻게 사용하는지 주목한다. 멋지다(neat).그리고 다음과 같은 것들도 있다:
(2.0).squareRoot() // 1.414213562373095
이는 2의 제곱근(square root)을 계산(computes)한다. 사인(sine) 45°는 2의 제곱근(square root)에 대해 1과 같다.
이것들을 언급하지 않는 것은 부끄러운(shame) 일이다:
max(5, 10) // 10 min(-5, -10) // -10
이들은 각각 두 숫자의 최대값(maximum)과 최소값(minimum)을 계산(compute)한다.
특히(particularly) 모험심(adventurous)이 있다면, 다음과 같이 결합(combine)할 수도 있다:
max((2.0).squareRoot(), Double.pi / 2) // 1.570796326794897
Naming data
컴퓨터 프로그래밍(computer programming)은 간단히 말해서 데이터를 조작(manipulating)하는 것이다. 화면(screen)에 표시되는 모든 내용은 CPU로 보내는(send) 숫자(numbers)로 줄일(reduced) 수 있다. 때로는(sometimes) 이 데이터를 다양한(various) 유형(types)의 숫자로 표현(represent)하고 작업하지만, 어떤 경우에는 데이터가 텍스트(text), 이미지(images) 및 컬렉션(collections)과 같은 더 복잡한 형태로 제공된다.
Swift 코드에서는 나중에 참조(refer to)할 수 있는 이름(name)을 각 데이터에 지정할 수 있다. 이름(name)에는 텍스트(text), 숫자(numbers) 또는 날짜(date)와 같이, 이름이 참조(refers to)하는 데이터의 종류(sort)를 나타내는(denotes) 유형 주석(type annotation)이 포함(carries with)된다. 이 장(chapter)에서는 몇 가지 기본 유형(basic types)에 대해 배우고, 이 책 전체에서 다른 많은 유형(types)을 접하게(encounter) 된다.
Constants
다음을 확인해 본다:
let number: Int = 10
이는
Int
유형(type)의number
라는 상수를 선언(declares)한다. 그런 다음 상수(constant) 값(value)을 숫자10
으로 설정한다.Note: 여기에는 또다른 연산자(operators)가 있다. 등호(equals sign,
=
)는 할당 연산자(assignment operator)로 알려져 있다.Int
유형(type)은 정수(integers)를 저장(store)할 수 있다. 소수(decimal numbers)를 저장(store)하는 방법은 다음과 같다:let pi: Double = 3.14159
이름(name)과 유형(type)이 다르다는 점을 제외(except)하면
Int
상수(constant)와 유사하다. 이번에는 상수(constant)가 높은 정밀도(precision)로 소수(decimals)를 저장할 수 있는Double
유형(type)을 사용한다.또한
Double
보다 낮은 정밀도(precision)로 소수(decimals)를 저장(stores)하는, 부동 소수점(floating point)의 약자(short)인Float
이라는 유형(type)도 있다. 사실(in fact)Double
은Float
보다 약 두 배 정도 정밀도(precision)가 높기 때문에,Double
이라고 한다.Float
는Double
보다 메모리(memory)를 덜 차지하지만, 일반적으로 숫자(numbers)에 대한 메모리 사용(memory use)은 그리 큰 문제(huge issue)가 아니며 대부분의 곳에서(in most places)Double
을 사용하는 것을 볼 수 있다.상수(constant)를 선언(declared)한 후에는 데이터를 변경(change)할 수 없다. 예를 들어(for example), 다음 코드를 고려(consider)해 본다:
number = 0
이 코드는 다음과 같은 오류(error)를 발생(produces)시킨다:
Cannot assign to value: 'number' is a 'let' constant
Xcode에서 다음과 같이 표시되는 오류(error)를 볼 수 있다:
상수(constants)는 변경(change)되지 않는 값(values)에 유용(useful)하다. 예를 들어(for example) 비행기를 모델링(modeling)할 때 설치된(installed) 총 좌석 수를 참조(refer to)해야 하는 경우, 상수(constant)를 사용할 수 있다.
사람의 나이와 같은 것에 상수(constant)를 사용할 수도 있다. 그들의 나이가 생일이 되면 변할지라도(even though), 해당 특정 순간(particular instant)에서만 그들의 나이에 관심을 가질(be concerned with) 수 있다.
Variables
종종 이름(name) 뒤(behind)에 있는 데이터를 변경(change)하려고 한다. 예를 들어(for example), 예금(deposits)과 출금(withdrawals)이 있는 은행 계좌(bank account)의 잔액(balance)을 추적(track)하는 경우, 상수(constant) 대신 변수(variable)를 사용할 수 있다.
프로그램의 데이터가 결코 변경(changed)되지 않는다면 다소 지루한(boring) 프로그램이 될 것이다. 하지만 보다시피 상수(constant) 뒤(behind)에 있는 데이터는 변경(change)할 수 없다.
일부 데이터를 변경(change)해야 하는 경우, 상수(constant) 대신(instead of) 변수(variable)를 사용하여 해당 데이터를 표시(represent)해야 한다. 다음과 같은 방식으로 변수(variable)를 선언(declare)한다:
var variableNumber: Int = 42
문장(statement)의 첫 부분만 다르다(different). let을 사용하여 상수(constants)를 선언(declare)하고, var를 사용하여 변수(variables)를 선언(declare)한다
변수(variable)를 선언(declared)한 후에는 유형(type)이 동일하게 유지(remains)되는 한, 원하는대로 자유롭게 변경(change)할 수 있다. 예를 들어(for example), 위에서 선언(declared)한 변수(variable)를 변경(change)하려면 다음과 같이 한다:
variableNumber = 0 variableNumber = 1_000_000
변수(variable)를 변경(change)하려면 새 값(new value)을 할당(assign)하기만 하면 된다.
Note: Swift에서는 선택적으로(optionally) 밑줄(underscores)을 사용하여, 큰 숫자를 보다 읽기 쉽게(human-readable) 만들 수 있다. 밑줄(underscores)의 수(quantity)와 위치(placement)는 개발자에게 달려 있다.
플레이 그라운드(playground)의 results sidebar를 자세히 살펴보기(take a closer look)에 좋은 때이다. 위의 코드를 플레이 그라운드(playground)에 입력(type)하면, 오른쪽의 results sidebar 각 행(each line)에서
variableNumber
의 현재 값(current value)이 표시된다:results sidebar에는 각 행(line)에 대한 관련 결과(relevant result)가 표시(exists)된다. 변수(variable) 또는 상수(constant)의 경우, 상수(constant)나 변수(variable)의 선언(declared) 또는 변수(variable)의 재할당(reassigned) 여부에 관계없이 결과는 새 값(new value)이 된다.
Using meaningful names
항상 변수(variables)와 상수(constants)에 대해 의미있는(meaningful) 이름(names)을 선택해야 한다. 좋은 이름(names)은 문서(documentation) 역할을 하며 코드를 읽기 쉽게(easy to read) 만든다. 좋은 이름(name)은 변수(variable) 또는 상수(constant)의 역할(role)을 구체적으로(specifically) 설명(describes)한다. 다음은 좋은 이름()의 몇 가지 예(examples)이다:
personAge
numberOfPeople
gradePointAverage
종종 나쁜 이름(name)은 충분히 설명(descriptive)되지 않는다. 다음은 잘못된 이름의 몇 가지 예(examples)이다:
a
temp
average
핵심(key)은 나중에 다시 읽을 때 변수(variable) 또는 상수(constant)가 무엇을 나타내는지(refers to) 이해하는 것이다. 완벽한(infallible) 기억력(memory)을 가지고 있다고 생각하는 실수(mistake)를 하지 마라. 컴퓨터 프로그래밍(computer programming)에서 하루나 이틀 후에 자신의 코드를 되돌아보고(look back) 그것이 하는 일을 잊어 버리는 것은 일반적(common)이다. 변수(variables)와 상수(constants)에 직관적(intuitive)이고 정확한(precise) 이름(names)을 지정하여 보다 쉽게 만들 수 있다.
또한 위의 이름들(names)이 어떻게 작성(written)되었는지 주목해 본다. Swift에서는 낙타 대문자(camel case) 이름(names)이 일반적(common)이다. 변수(variables) 및 상수(constants)의 경우, 다음 규칙(rules)에 따라 이름(names)을 적절하게(properly) 지정한다:
- 소문자(lowercase letter)로 시작한다.
- 이름(name)이 여러 단어(multiple words)로 구성(made up of)된 경우, 함께 결합(join)하고 다른 단어는 대문자(uppercase letter)로 시작한다.
- 이 단어 중 하나가 약어(abbreviation)인 경우, 동일한 대소문자(same case)로 전체 약어(abbreviation)를 작성한다(e.g. :
sourceURL
및urlDescription
).
Swift에서는 전체 범위의 유니코드 문자(Unicode characters)를 사용할 수도 있다. 예를 들어(for example), 다음과 같이 변수(variable)를 선언(declare)할 수 있다:
var 🐶💩: Int = -1
재미있을 수 있지만 이와 같은 특수 문자(special characters)는 주의(caution)해야 한다. 그것들은 입력(type)하기 더 어렵고, 즐거움(amusement)보다 더 큰 고통(pain)을 가져올 수 있다.
이와 같은 특수 문자(special characters)는 Swift 코드보다는 저장(store)하는 데이터에 더 적합할 수 있다. 9장(chapter), "Strings"에서 유니코드(Unicode)에 대해 자세히 알아볼 수 있다.
Increment and decrement
일반적으로 연산(operation)은 변수(variable)를 증가(increment)시키거나 감소(decrement)시킬 수 있어야 한다. Swift에서는 다음과 같이 사용한다:
var counter: Int = 0 counter += 1 // counter = 1 counter -= 1 // counter = 0
counter
변수(variable)는0
으로 시작한다. 증가(increment)는 값(value)을1
로 설정(sets)하고, 감소(decrement)는 값(value)을 다시0
으로 설정(sets)한다.이러한 연산자(operators)는 덧셈(addition) 또는 뺄셈(subtraction)을 수행(perform)한다는 점을 제외하면, 할당 연산자(assignment operator,
=
)와 유사(similar to)하다. 그들은 변수(variable)의 현재 값(current value)을 취하고, 주어진 값(value)을 더하(add)거나 빼(subtract)서 그 결과를 변수(variable)에 할당(assign)한다.즉(in other words), 위의 코드는 다음에 대한 축약형(shorthand)이다:
var counter: Int = 0 counter = counter + 1 counter = counter - 1
마찬가지로(similarly,)
*=
및/=
연산자(operators)는 각각(respectively) 곱셈(multiplication)과 나눗셈(division)에 대해 동일하게 동작한다:counter = 10 counter *= 3 // same as counter = counter * 3 // counter = 30 counter /= 2 // same as counter = counter / 2 // counter = 15
Mini-exercises
Xcode의 코드를 따라오지(following along) 않았다면, 지금이 새로운 플레이 그라운드(playground)를 만들고 직접 테스트(test)를 위한 몇 가지 연습(exercises)을 해 볼 시간이다.
myAge
라는Int
유형(type)의 상수(constant)를 선언(declare)하고, 이를 자신의 나이(age)로 설정(set)한다.averageAge
라는Double
유형(type)의 변수(variable)를 선언(declare)한다. 초기화 시(initially)에는 자신의 나이(age)로 설정(set)한다. 그런 다음, 평균(average) 연령인30
세로 설정(set)한다.testNumber
라는 상수(constant)를 만들고, 원하는 정수(integer)로 초기화(initialize)한다. 다음으로evenOdd
라는 또 다른 상수(constant)를 만들고testNumber
를 2로 나머지 연산(modulo)한 결과와 동일(equal to)하게 설정(set)한다. 이제testNumber
를 다양한 숫자로 변경(change)하고evenOdd
의 값을 확인(notice)해 본다.answer
이라는 변수(variable)를 만들고, 값(value)을0
으로 초기화(initialize)한다.1
을 증가(Increment)시킨다. 그리고 여기에10
을 더(add)한다.10
을 곱(multiply)한다. 그런 다음(then) 오른쪽 시프트(shift)3
을 적용한다. 이 모든 연산(operations)을 마친 후, 답(answer)이 무엇인지 확인한다.
Challenges
계속 진행하기 전에 변수(variables) 및 상수(constants)에 대한 지식(knowledge)을 확인(test)하기 위한 몇 가지 챌린지(challenges)가 있다. 직접 해결(solve)하려고 시도하는 것이 가장 좋지만, 막힌다면(get stuck) 해답(solutions)을 확인할 수 있다. 이러한 파일은 다운로드(download)와 함께 제공되거나, 서문(introduction)에 나열된(listed in) 소스 코드 링크(source code link)에서 확인할 수 있다.
Challenge 1: Variables
myAge
라는Int
유형 상수(constant)를 선언(declare)하고, 나이(age)를 설정한다. 또한,dogs
라는Int
유형 변수(variable)를 선언(declare)하고, 기르는 개의 마리 수를 설정한다. 그리고 나서, 새 강아지를 분양하여dogs
변수(variable)를 1 씩 늘린다고 상상해 본다.Challenge 2: Make it compile
주어진 코드는 다음과 같다:
age: Int = 16 print(age) age = 30 print(age)
컴파일(compiles)되도록 첫 번째 행(line)을 수정한다.
var
와let
중 어떤 것을 사용해야 할 지 생각해 본다.Challenge 3: Compute the answer
주어진 코드는 다음과 같다:
let x: Int = 46 let y: Int = 10
다음 코드를 추가 할 때, 어떤
answer
이 동일한지 확인해 본다:// 1 let answer1: Int = (x * 100) + y // 2 let answer2: Int = (x * 100) + (y * 100) // 3 let answer3: Int = (x * 100) + (y / 10)
Challenge 4: Add parentheses
다음 계산(calculation)에 괄호(parentheses)를 최대한 많이 추가하여 계산(calculation) 결과가 변경(change)되지 않도록 한다.
8 - 4 * 2 + 6 / 3 * 4
Challenge 5: Average rating
Double
유형의rating1
,rating2
,rating3
이라는 세 개의 상수(constants)를 선언(declare)하고, 각각에 값(value)을 할당(assign)한다. 세 개의 평균(average)을 계산하여 그 결과를averageRating
이라는 상수(constant)에 저장(store)한다.Challenge 6: Electrical power
전자 기기(electrical appliance)의 전력(power)은 전압(voltage)에 전류(current)를 곱하여 계산(calculated)한다.
Double
유형(type)의voltage
상수(constant)를 선언(declare)하고 값(value)을 할당(assign)한다. 그런 다음Double
유형(type)의current
상수(constant)를 선언(declare)하고 값(value)을 할당(assign)한다. 마지막으로(finally), 방금 생성한 전자 기기(electrical appliance)의 전력(power)을 계산(calculate)하여Double
유형(type)의power
상수(constant)에 저장(storing)한다.Challenge 7: Electrical resistance
그런 다음 이러한 기기(appliance)의 저항(resistance)은 전력(power)을 전류(current)의 제곱(squared)으로 나누는(divided) 지루한 방법(long-winded way)으로 계산(calculated)할 수 있다. 저항(resistance)을 계산(calculate)하여
Double
유형(type)의resistance
라는 상수(constant)에 저장(store)한다.Challenge 8: Random integer
arc4random()
함수(function)를 사용하여 임의의 정수(random integer number)를 만들 수 있다. 이는 0에서 4294967295 사이의 숫자를 선택(picks)한다. 나머지(modulo) 연산자(operator)를 사용하여, 이 난수(random number)를 원하는 범위(range)로 자를(truncate) 수 있다.randomNumber
상수(constant)를 선언(declare)하고,arc4random()
으로 생성된(generated with) 난수(random number)를 할당(assign)한다. 그런 다음diceRoll
상수(constant)를 계산(calculate)하고 방금 찾은 난수(random number)를 사용하여 1과 6 사이의 난수(random number)를 만든다. (Hint:arc4random()
를 사용하려면(access to),import Foundation
행(line)을 포함(include)해야 한다. 난수(random number)를 생성하는 메서드(method)는 원시적(primative)으로 보인다. 더 쉽고 명확하며 표현적인 방법을 4장(chapter), “Advanced Control Flow”에서 배우게 될 것이다.)Challenge 9: Quadratic equations
2차 방정식(quadratic equation)은
a⋅x² + b⋅x + c = 0
형식(form)이다. 이를 만족(satisfy)하는x
의 값(values)은 방정식(equation)x = (-b ± sqrt (b²-4⋅a⋅c)) / (2⋅a)
를 사용하여 구할(solved) 수 있다. Double 유형(type)의a
,b
,c
세 개의 상수(constants)를 선언(declare)한다. 그런 다음 위의 방정식(equation)을 사용하여x
에 대한 두 값(values)을 계산(calculate)한다 (±는 플러스(plus) 또는 마이너스(minus)를 의미하므로 각각에 대해 하나의x
값(value)을 가진다). 결과를Double
유형(type)의root1
,root2
상수(constants)에 저장(store)한다.Key points
- 컴퓨터는 가장 기본적인 수준(most fundamental level)에서 간단한 수학(mathematics)을 수행(perform)한다.
- 프로그래밍 언어(programming language)를 사용하면 컴파일러(compiler)가 CPU를 실행(execute)할 수 있는 명령어(instructions)로 변환(converts into)하는 코드를 작성(write)할 수 있다.
- 컴퓨터는 이진수(binary)라고도 하는 2진법(base 2) 형식(form)의 숫자로 작동(operate)한다.
- Swift 코드를 작성(write)하는 데 사용하는 IDE는 Xcode이다.
- 코드가 어떻게 실행(executing)되는지에 대한 즉각적인 피드백(immediate feedback)을 제공(providing)하는 플레이 그라운드(playgrounds)를 사용해 Swift 코드를 빠르고(quickly) 효율적(efficiently)으로 작성(write)하고 확인(test)할 수 있다.
- 코드 주석(comments)은
//
로 시작하는 행(line) 또는/*
와*/
로 감싸진(bookended) 여러 행(multiple lines)으로 표시(denoted)한다. - 주석(comments)을 사용하여 코드를 문서화(document)한다.
print
를 사용하여 디버그 영역(debug area)에 정보(information)를 출력(output)할 수 있다.- 산술 연산자(arithmetic operators)는 다음과 같다:
Add: + Subtract: - Multiply: * Divide: / Remainder: %
- Swift에는
min()
,max()
,squareRoot()
,sin()
,cos()
등 많은 함수(functions)가 있다. 이 책을 통해 더 많은 것을 배울 것이다. - 상수(constants)와 변수(variables)는 데이터에 이름을 부여한다.
- 상수(constant)를 선언(declared)한 후에는 데이터를 변경(change)할 수 없지만, 변수(variable)는 데이터를 언제든지(at any time) 변경(change)할 수 있다.
- 자신과 동료들의 두통(headaches)을 덜기 위해, 항상 변수(variables)와 상수(constants)에 의미있는(meaningful) 이름(names)을 지정한다.
- 연산(arithmetic)을 수행(perform)한 다음, 다시 변수(variable)에 할당(assign)하는 연산자(operators)는 다음과 같다:
Add and assign: += Subtract and assign: -= Multiply and assign: *= Divide and assign: /=
'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 3: Basic Control Flow (0) 2021.06.16 Chapter 2: Types & Operations (0) 2021.03.16