CLOSE SEARCH

Swift – Change the flow

Swift는 애플에서 4년간 공들인 언어답게 Objective-C 언어에서 제공하는 기본적인 반복문과 제어문을 넘어서, 반복의 범위를 더 쉽게 지정할 수 있는 문법, Value Binding/Optional Binding과 제어문의 활용 등을 통해 복잡한 코드를 이전보다 훨씬 간결하게 표현할 수 있도록 도와줍니다. 특히 Switch문의 경우 Objective-C에서는 제공하지 않던 다양한 기능을 제공합니다. 저는 개인적으로 코드가 간결하게 정리되지 않는 느낌이 들어서(지극히 주관적입니다^^;) switch 문을 선호하지 않았지만, Swift에서는 너무 매력적인 기능들이 많아서 switch문을 적극적으로 사용하게 될 것 같습니다.

For

Swift는 for-in, for-condition-increment 라고 부르는 두가지 형태의 for 반복문을 제공합니다. for-in은 배열이나 딕셔너리를 순회할 때 주로 사용했던 for문과 유사하고, for-condition-increment는 C부터 기본적으로 제공했던 반복문이라고 보시면 됩니다.

for-in

for-in은 앞서 설명한 것과 같이 주로 컬렉션의 요소들을 순회할 때 주로 사용하게 되는 반복문입니다.

Objective-C의 for-in과 가장 구분되는 점은 코드 1-1과 같이 closed range operator(…, 범위 연산자)를 사용해서 반복 범위를 쉽고 직관적으로 선언할 수 있고, 문자열 순회도 더욱 직관적이라는 것입니다. 범위 연산자에 대한 내용은 아래의 글을 참고해 주시기 바랍니다.

참고: Swift – Operators && Operator Function

 

코드 1-2는 문자열 배열을 순회하는 코드입니다. for-in문은 배열을 순회하면서 각 요소를 item “상수”에 할당합니다. 그래서 item을 println 함수로 출력하면 배열에 포함된 각 문자열이 출력되는 것입니다. 만약, for-in 문 내부에서 item 상수를 사용할 필요가 없다면, _(언더스코어) 문자를 통해 값을 무시하도록 지정할 수도 있습니다.

for-in문을 사용해서 딕셔너리를 순회하는 경우에는 튜플을 활용해야 합니다.

코드 1-3과 같이 languages 딕셔너리를 순회하면서 k 와 v 상수에 키와 값을 각각 할당합니다. Dictionary는 기본적으로 정렬되지 않은 컬렉션이기 때문에 출력 결과는 실행시에 달라질수도 있습니다.

for-condition-increment

앞서 설명한 for-in을 통해서 대부분의 반복 작업을 처리할 수 있지만, 다른 언어에서 많이 사용되는 기본적인 형태의 for문도 함께 제공합니다. 아래의 코드에서 알 수 있듯이, 괄호가 없다는 것을 제외하면 Objective-C 또는 C의 반복문과 동일한 문법을 가지고 있습니다.

이전에는 for 문 내부의 코드가 한줄인 경우 { }도 생략할 수 있었기 때문에, Swift에서도 가능하지 않을까 생각되실수도 있지만, Swift에서는 { }가 필수입니다. for문 뿐만 아니라 다른 반복문과 제어문에도 적용되는 사항이니 반드시 기억해 두시기 바랍니다.

 

While

while문도 for문과 마찬가지로 조건식 부분의 괄호가 생략되었고, { }는 생략할 수 없습니다.

 

If

if문의 문법은 다른 언어들과 매우 유사합니다. 앞서 강조했던 것처럼 조건식을 적어주는 부분의 괄호는 생략되었고 각 조건이 일치할 때 수행할 코드는 라인 수에 관계없이 반드시 { }로 감싸주어야 합니다.

 

Switch

switch문의 경우 Objective-C와 뚜렷하게 구별되는 여섯가지 특징이 있습니다. 첫번째 특징은 코드 4-1과 같이 case 사이에 break를 적어주지 않는다는 것입니다. 바꿔 말하면, Fallthrough를 지원하지 않습니다.

Objective-C의 경우 매칭되는 case문부터 break;를 만날때까지 모든 코드를 수행하지만, Swift에서는 매칭되는 case의 코드를 수행한 후 바로 리턴합니다. 그러므로 Objective-C 코드를 Swift로 이전하거나 새롭게 Swift 프로그램을 작성할 때는 Fallthrough 패턴을 사용하지 않도록 주의해야 합니다. 여러 case를 동시에 매칭시키고자 하는 경우에는 각각을 case 문으로 명시하지 않고 5번 라인과 같이 콤마(,)로 구분해 주면 됩니다. 16,17번 라인과 같은 방식은 Swift에서 오류로 간주됩니다.

두번째 특징은 매칭시킬수 있는 자료형이 다양하는 것입니다. Objective-C와 다른 이전의 언어들은 정수형만 매칭시킬수 있었습니다. 하지만 Swift는 정수형, 실수형, 문자열들을 모두 매칭시킬 수 있습니다.

세번째 특징은 case 문과 범위 연산자를 조합하여 값의 범위를 매칭시키거나, 튜플을 사용해서 두개 이상의 값을 매칭시킬수도 있다는 것입니다.

네번째 특징은 default: 를 생략할 수 없다는 것입니다. 대부분의 다른 언어에서는 default: 를 생략할 수 있지만, Swift에서는 이것을 오류로 간주합니다.

다섯번째 특징은 Value Binding을 이용해서 case와 매칭되는 값을 변수 또는 상수에 바인딩할 수 있다는 것입니다.

3번 라인에서는 튜플의 첫번째 요소가 width 상수로 바인딩되고, 5번 라인에서는 튜플의 두번째 요소가 height 상수에 바인딩 됩니다. 7번 라인과 같이 튜플의 모든 요소를 바인딩 대상으로 지정하는 경우에는 default:를 생략할 수도 있습니다. 만약, 코드 4-5에서 screenRes의 값이 (2048, 1600)이라면 5번 라인의 case와 매칭되고 1600이 height 상수에 할당되는 것입니다. 여기에서 선언된 width, height는 임시 상수이기 때문에 해당 case문 내에서만 사용할 수 있습니다.

마지막 특징은 where 절을 통해 부가적인 조건을 추가할 수 있다는 것입니다. 코드 4-5에서 해상도가 320, 480인 경우에만 iPhone 화면 해상도로 판단하도록 하려면 코드 4-6과 같이 case 뒤에 where절을 추가해 주면 됩니다.

코드 4-6를 실행해보면 첫번째 case와 매칭되고 where 절의 조건도 일치하므로 4번 라인이 수행되지만, 만약 screenRes 값이 (321, 480) 이라면 case는 매칭되지만 where 절의 조건과 일치하지 않기 때문에 가장 마지막 case 문이 실행됩니다.

fallthrough

fallthrough는 switch문에서 첫번째로 매칭되는 case 문부터 break; 만날 때까지 코드가 계속해서 수행되는 동작을 설명하는 용어입니다. 앞서 설명한 것처럼 Swift는 이러한 동작을 허용하지 않기 때문에 Objective-C의 switch에 비해 더 직관적이고 안정적인 코드를 작성할 수 있게 되었습니다. 만약 swift의 switch 문에서 fallthrough를 지원하도록 하려면, 새롭게 추가된 fallthrough 키워를 통해 명시적으로 지정해 주어야 합니다. Objective-C에서는 break; 통해 기본적인 fallthrough를 제한했지만, Swift에서는 반대로 fallthrough 키워드를 통해 falltough를 활성화 시키는 것입니다. 코드 4-2의 첫번째 case에 fallthrough를 추가한 코드는 다음과 같습니다.

코드 4-2와 달리 5번 라인에 있는 fallthrough로 인해 “google”과 매칭되는 android도 함께 출력됩니다. fallthrough는 하나의 case에만 영향을 주기 때문에, Objective-C와 유사한 형태의 switch를 구현하려면 모든 case에 각각 fallthrough를 추가해 주어야 합니다.

 

Labeled Statements

continue와 break는 다른 언어와 마찬가지로 제어문이나 반복문의 실행흐름을 조작하는 역할을 담당합니다. 기본적으로 조작의 범위가 자신과 가장 인접한 제어문이나 반복문으로 한정되지만, Swift에서는 labeled statements라는 문법을 통해 switch나 반복문에 이름을 붙이고, 인접하지 않은 경우에도 실행흐름을 조작할 수 있는 기능을 제공합니다. labeled statements는 switch문, for, while 반복문에만 적용할 수 있습니다.

코드 5-1에서 5번 라인의 break는 j 값이 5인 경우 인접한 for문의 반복을 종료하기 때문에 각 단 * 5 까지의 결과만 출력이 됩니다.

코드 5-2에서는 for문에 각각 outer, inner라는 이름을 붙여주고 있습니다. 1번, 2번 라인처럼 switch, for, while문의 첫번째 라인 앞에 이름과 콜론(:)을 붙여주면 됩니다. 콜론(:) 뒤에 오는 공백이 반드시 필요한 것은 아니지만 가독성을 위해서는 공백을 추가해 주는 것이 좋습니다. 이 코드는 5번 라인에서 break를 호출할 때 for문에 붙이 outer라는 이름을 명시적으로 지정해주고 있습니다. 그래서 인접한(inner라는 이름으로 지정한) for문이 아닌 전체(outer라는 이름으로 지정한) for문의 실행이 종료됩니다.
ps. Facebook 페이지에 가입해서 함께 정보를 공유해보아요 :) https://www.facebook.com/groups/254425194763076/

ps. 제가 올린 글들은 출처만 밝혀주신다면 자유롭게 공유하실 수 있습니다. 부족한 내용이지만 더 많은 개발자분들께 도움이 되었으면 하는 바램입니다.

Filed under: Swift