본문 바로가기

Programming/Swift for Beginners

[Swift] 021 Additional Tips for Arrays and Dictionaries (배열과 사전의 추가적인 팁) for beginners



믿을만한 선언문(COUNTING ON IT)

일반적으로 for-in 문은 열거형으로 사용합니다. Swift가 제공하느 특별한 문법을 사용해 개발자들은 특정 숫자의 범위를 세는 for-in 반복문을 구성할 수 있습니다. 여러 항목이 들어 있는 컬렉션이나, 어떤 범위, 배열 안에 들어 있는 항목에 대해서, 또는 문자열에 들어 있는 각 문자에 대해서 반복을 할 때 for-in 반복문을 사용합니다. for-in 반복문은 다음과 같습니다.

for loopVariable in startNumber...endNumber

for-in 반복문은 각각의 루프에 대한 값을 가진 루프 변수가 필요합니다. for-in문은 키워드 in 다음에 시작 번호가 오고 그 다음은 "..."그리고 끝 번호를 순서대로 넣습니다.

마침표 세 개(...)는 처음 시작하는 번호와 끝나는 번호가 이 범위 안에 들어간다고 얘기해주는 것입니다. for 반복문은 시작하는 번호를 루프 변수에 할당하면서 시작하고 루프를 실행하면서 루프 변수에 1을 추가합니다. 그리고 변수를 끝 번호와 비교합니다. 루프 변수가 끝 번호보다 작거나 동일하면 루프는 계속해서 실행됩니다.

1행에서 루프 변수로 사용될 정수형 변수 loopCounter를 선언했습니다. 

2행은 범위를 정하는 ... 을 사용한 for-in 문을 가지고 있습니다. 그리고 숫자 1을 시작 번호로 정하고 끝 번호로 10을 넣었습니다. 3행은 loopCounter변수 자체를 곱한 결과를 보여주는 print 명령어를 넣었습니다. 마지막으로 4행에는 오른쪽 괄호 } 를 넣어 REPL에 for-in 반복문이 실행되어야 한다는 실호를 보냈습니다. 그 다음에 Swift는 1부터 10까지의 곱하기 결과를 보여주는 10개의 행을 출력합니다.

카멜표기법(CAMELCASE)
 텍스트를 보고 변수 이름에 소문자와 대문자가 같이 사용된 것을 눈치챘을 것입니다. 첫 번째 단어가 소문자로 시작하
 고 그 뒤에는 대문자를 썼습니다. 이런 것을 카멜 표기법이라고 부르며 Object-C 언어에서 일반적으로 사용하는 방
 식입니다. 카멜 표기법의 예로는 myFirstBirthday, rockyMountainHigh, bedAndBreakfast 등이 있습니
 다. Swift언어도 이 표기법을 따르고 있습니다. 사용자가 꼭 카멜 표기법을 코드에 사용할 필요는 없지만 이 방법을
 따르거나 다른 방법을 사용하더라도 동일한 방법을 일관되게 사용하는 것을 권장합니다.

범위에 포함 또는 배제 (INCLUSIVE OR EXCLUSIVE)

범위를 정하는데 사용된 ... 문법의 또 다른 버전은 ..< 문법입니다. ... 문법을 사용하면 양쪽 끝의 값을 모두 범위에 포함하게 됩니다. 반면에 ..< 문법을 사용해서 범위를 지정하면 맨 마지막 값은 제외됩니다. 이 연산자는 끝 번호보다 1(one value)이 적으면 루프를 반복시키라고 명령합니다. 이전 예제를 다시 사용해 ... 연산자를 ..< 으로 대체해서 다른 점이 무엇인지 확인해 보겠습니다.

루프가 숫자 9로 끝이 났습니다. 끝 번호인 10보다 1 작은 수 입니다.

이 방법이 왜 유용한 것일까 궁금할 것입니다. 결국에는 범위를 정하는 ... 연산자를 사용해 10을 9로 대체해도 동일한 결과를 얻을 수 있는데 말입니다.

실제로 이 연산자는 배열과 같은 컬렉션을 반복할 때 사용하기에 유용합니다. 컬렉션의 배열은 인덱스를 가지고 있으며 이 인덱스는 항상 0부터 시작합니다.

위 예제처럼 배열 크기(총 9개)를 루프 제한값(0에서 9까지)으로 사용하는 것이 좀 더 자연스럽게 보일 수 있습니다. 

개발자의 선호도와 상관없이 배열은 항상 인덱스가 0부터 시작하기 때문입니다. 따라서 마지막 구성 요소의 인덱스는 배열에 있는 전체 요소의 수보다 1이 작습니다. 또한, 배열을 반복할 때 보완해야 한다는 사실도 잊으면 안 됩니다.

기존 언어와 유사한 부분(FOR OLD TIME'S SAKE)

Swift는 for 반복문의 다른 버전이 있습니다. C 언어가 익숙한 사용자라면 이미 아는 것입니다. in 키워드를 사용하지 않지만 for 문에 initialization, evaluation, modification 이 있습니다.

  • 초기화(initialization): 여기에서는 루프 변수가 초기화 됩니다.
  • 평가(evaluation): 이 위치에서는 테스트가 이루어집니다. 결과가 참인 동안에는 루프가 실행됩니다.
  • 수정(modification): 일반적으로 이곳에서 기본적으로 루프 변수가 수정됩니다.

이런 형태의 for 반복문이 가지고 있는 장점은 수정(modification) 단계가 단순하게 1씩 증가하는 것이 아니라 더 많은 일을 할 수 있게 해줍니다. 숫자를 증가시킬 수도 있고 반대로 감소시킬 수도 있습니다.

for 반복문의 수정 단계에서 증가 값으로 2를 선택하면 배열 내에서 루프가 한 항목씩 건너띄어 반복됩니다. 

또한, 반복문을 역방향으로 가게 할 수도 있습니다. 그러나, 배열의 첫 번째 요소의 인덱스는 0을 가지고 있으니 0미만으로는 가지 않도록 신경 써야 합니다.

for 반복문 형태의 유연성 때문에 서수 순서를 따르지 않아도 되는 컬렉션이나 계산 결과의 컬렉션에 대한 트래버스(traverse)를 가능하게 해줍니다.

약식 사용(WRITING SHORTHAND)

앞서 사용한 두 예제에 for 반복문을 수정한 코드는 다음과 같습니다.

loopCounter = loopCounter + 2
loopCounter = loopCounter - 2

첫 번째 행은 loopCounter에 2를 더하고 두 번째 행은 2를 뺍니다.

위 예제가 살짝 긴 것 같지만 Swift는 변수에 숫자를 더하고 빼는 더 간결한 문법이 있습니다.

3을 anotherLoopCounter 변수에 할당했습니다. 

+= 문법을 사용해 변수를 다시 입력하는 것을 피했습니다. 이런 문법은 약식 메서드로 "왼쪽의 변수에 오른쪽의 변수를 더하기"하라는 의미입니다. 변수 이름 자체를 입력해 REPL로 하여금 값을 보여주고 그 값을 임시 변수에 할당하게 했습니다.

동일한 논리가 빼기에도 적용됩니다.

더 간결하게 만들 수 있습니다. 

숫자 1씩 증가시키고 싶다면 더 짧은 문법 ++ 만 넣어 사용할 수 있습니다.

차이점이 보이시나요? anotherLoopCounter가 증가하기 전에는 2였습니다. 

증가한 후에도 왜 2를 반환한 것일까요? 1씩 증가한 것이면 2가 아니라 3을 반화내야 하는 것이 아닐까요?

지금 보고 있는 것은 증가 연산의 부작용을 보는 것입니다. 변수 이름 다음에 ++ 를 넣는것은 증가하기 이전의 값을 반환하도록 합니다. 이것이 문제의 요인이었습니다. 이 때문에 값 2가 임시 변수 $R2에 할당된 것입니다. REPL에 변수를 다시 보여달라고 요청하면 증가된 값을 보여줄 것입니다.

이는 후치 증가(post increment)라고 부릅니다.

 변수를 평가한 후에 증가가 일어납니다. 또한, 빼기 연산은 후치 감소(post decrement)를 사용합니다.

후치 증가가 있는 것처럼 전치 증가도 있습니다.

anotherLoopCounter가 2였지만 지금은 3인 것에 주의하여야합니다. 

anotherLoopCounter를 다시 출력하면 같은 숫자를 보여줄 것입니다.

예상했던 대로 결과가 나왔습니다.

마지막으로 전치 감소 예제입니다.

추후에 더 많은 약식 증가/감소 연산자를 살펴보겠습니다. 약식을 사용하면 길게 입력해야 하는 불편을 덜어줍니다. 변수에서 숫자를 더하거나 뺄 때 자연스럽게 사용할 수 있도록 계속되는 연습이 필요할 것입니다.