CLOSE SEARCH

Swift – Quick Tour

새로운 언어는 프로그래머에게 어떤 의미를 가질까요? 처음부터 다시 배워야 하는 골칫덩어리? 아니면 새로운 자극제?
Swift를 바라보는 시각은 사람마다 모두 다르겠지만, 저처럼 예상하지 못했던 한방(?)에 당황하신 분들은 많으시리라 생각됩니다.
Objective-C라는 멋진 언어를 두고 새로운 언어를 개발자들에게 던져준 애플의 의도가 무엇일까요? Swift를 Java나 C#처럼 앱과 웹을 모두 개발할 수 있는 언어로 만들려는 것일까요?

정확히 알 수 있는 한가지 사실은 공부해야 할 언어가 하나 더 늘었고, 앞으로도 iOS & Mac 개발을 계속하려면 반드시 배워야 하는 언어라는 점입니다.
저 역시 당분간은 새로운 언어를 공부하는데 집중하면서 이 글을 읽고 계시는 여러분들과 새로운 언어에 대해서 많은 부분을 나눌 생각입니다. :)
이번 글에서는 “The Swift Programming Language”에 나와있는 내용을 토대로 Swift에 대해 아주 간략하게 살펴보고자 합니다.

우선 Swift에 대한 간략한 소개와 가이드는 아래의 링크에서 보실 수 있습니다.
https://developer.apple.com/swift

 

Hello World!

java를 해 보신 분이라면 익숙한 메소드 이름이 보이실 겁니다. 정말 놀라운 사실은 위의 코드 한줄이 완전한 하나의 프로그램이라는 것입니다. 대부분의 언어에서는 main 함수라는 entry-point가 있고, 헤더를 임포트하는 코드도 필요합니다. 그러나 Swift는 전역 범위(global scope)에 작성된 코드를 진입점으로 인식하고 실행하기 때문에 main 함수가 필요치 않습니다. 그리고 마지막에 세미콜론(;)이 빠진것은 오타가 아닙니다!  문자열을 감싸는 따옴표 앞에 @를 적어주지도 않습니다. 이러한 차이점 때문에, 작성해야할 코드의 양은 줄어들겠지만, 코딩 스타일이 손에 익기 전까지는 수많은 오류를 보게 될 것 같습니다. 특히, 세미콜론;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;이 걱정입니다.

 

Variable & Constant

변수와 상수는 각각 var, let 키워드를 통해 선언합니다. 변수나 상수의 이름은 영문자, 숫자, 일부 특수문자로 제한되어 있지 않습니다. 유니코드로 표현할 수 있는 모든 문자를 사용할 수 있기 때문에, 한글로 변수명을 지정하거나 스마일과 같은 특수문자를 사용해서 이름을 지정할 수도 있습니다.

Swift 컴파일러는 상수나 변수에 저장된 값의 자료형을 추론할 수 있기 때문에 위의 코드와 같이 자료형을 적어주지 않아도 됩니다. 즉, myVariable 에 할당된 초기 값이 정수(42)이므로 컴파일러는 이 변수가 정수형 변수라고 인식하게 됩니다. 자료형을 명시적으로 지정하고 싶다면 아래의 문법을 사용할 수 있습니다.

암시적 형변환은 지원하지 않으며, 반드시 변환하고자 하는 자료형의 인스턴스를 생성해 주어야 합니다.

위의 코드와 같이 정수 94를 문자열로 변환하기 위해서는 String(width)와 같이 명시적으로 문자열 객체를 생성해야 합니다. 만약,  label + width와 같이 코드를 작성하고 Xcode에서 컴파일 해보면, 문자열과 정수를 더하도록 재정의된 + 연산자가 없다는 오류가 발생합니다.

 

Format String

Objective-C에서는 문자열에 특정 값을 추가해서 형식화된 문자열을 만들기 위해서 stringWithFormat:과 같은 메소드를 사용했었지만, Swift에서는 좀 더 쉽게 형식화된 문자열을 만들 수 있습니다. 아래의 코드와 같이 \를 쓴 다음 괄호 안에 표현식을 넣어주면 됩니다.

 

Array & Dictionary

배열과 딕셔너리는 브라켓([ ])을 사용해서 생성하고, 각각 인덱스와 키를 통해서 값을 읽을 수 있습니다.

빈 배열이나 딕셔너리를 생성하는 코드는 다음과 같습니다. 다른 언어에서 널리 사용되고 있는 일반화 프로그래밍 기법을 지원합니다.

배열이나 딕셔너리에 들어가는 값의 자료형을 컴파일러가 추론할 수 있다면, 다음과 같이 자료형을 생략하고 간략하게 작성하는 것도 가능합니다.

 

if, switch, for, while

Swift는 익숙한 제어문(if, switch)과 반복문(for-in, for, while, do-while)을 모두 제공합니다. Objective-C와 달리 조건을 기술하는 부분의 괄호는 생략할 수 있지만, 코드를 감싸는 대괄호({})는 반드시 적어주어야 합니다. 다른 언어의 경우 for 문에서 실행하는 코드가 한줄어거나, if 문의 코드가 한줄인 경우 대괄호를 생략할 수 있지만,  Swift에서는 이러한 예외를 허용하지 않습니다.

if 문에서 조건은 반드시 Boolean 표현식이어야 하며, C나 Objective-C에서와 같이 0과의 비교를 통해 참/거짓을 암시적으로 판단하는 방식도 지원하지 않습니다.

if와 let 키워드를 함께 사용하면 optional value를 사용할 수 있습니다. 자료형 뒤에 ?를 적어주면 해당 값이 optional 하다는 것을 나타냅니다. 아래의 코드에서 optionalName 값이 nil인 경우, if 문은 실행되지 않습니다. 반대로 이 값이 nil이 아니고, unwrapped 되어(c#의 unboxing과 유사한 개념)  let 뒤의 상수에 할당된다면, if 문 내의 코드가 실행되고 name를 이 코드에서 사용할 수 있게 됩니다.

다른 언어의 switch문은 대부분 정수형의 동등비교만을 지원하는데 비해, Swift의 switch 문은 다양한 자료형과 비교 작업을 지원합니다. 가장 중요한 차이점은 다른 언어의 switch문은 일치하는 case부터 break를 만날 때까지 모든 코드를 실행하지만, Swift의 경우 해당 case만을 실행하고 바로 리턴한다는 것입니다. 그렇기 때문에 case 사이에 break가 존재하지 않습니다.

딕셔너리를 순회하기 위해서는 다음과 같이 for-in문을 사용할 수 있습니다.

while문과 do-while문은 조건 부분의 괄호를 생략할 수 있다는 것을 제외하면 다른 언어와 유사합니다. if문과 마찬가지로 {}는 어떠한 경우에도 생략할 수 없다는 점에 유의해야 합니다.

for-in 문을 사용할 때는 ..과 …을 사용해서 반복값의 범위를 지정할 수 있습니다. ..의 경우 최대값을 제외하고 반복문을 수행하지만, …의 경우 최대값을 포함해서 반복문을 수행합니다. 즉, 0..3 인 경우에는 0에서 2사이를 반복하지만, 0…3인 경우에는 0에서 3사이를 반복하는 것입니다.

 

Function

함수를 선언할 때는 func 키워드를 사용합니다.

대부분의 프로그래밍 언어에서 리턴형이 함수(또는 메소드) 선언의 가장 앞에 위치했지만, Swift의 경우 파라미터를 기술하는 괄호 뒤에 ->를 적고 리턴형을 기술합니다. 처음에는 잘 이해가 되지 않을 수도 있지만, ->를 기준으로 분리해서 보면 구조를 쉽게 파악할 수 있습니다.

함수를 호출하는 방식은 마지막에 세미콜론을 적어주지 않는다는 것을 제외하면 C나 java에서 사용하는 방식과 동일합니다.

Swift에서는 튜플을 사용해서 두개 이상의 값을 리턴하는 것도 가능합니다.

가변 파라미터도 지원하며, 함수 내부에 배열 형태로 전달됩니다.

다른 함수를 내포하는 것도 가능하며, 내포된 함수는 외부 함수에 범위에 포함되어 있는 변수에 접근할 수 있습니다.

그리고 함수 자체를 리턴하거나 다른 함수를 파라미터로 받을 수도 있습니다.

Swift의 함수는 Closure의 특수한 형태이기 때문에, 자바스크립트의 클로져, C#이나 파이썬의 람다식과 동일한 기능을 제공합니다.
즉, 아래의 코드와 같이 익명 함수를 파라미터로 전달하는 것도 가능하며, 이 경우에는 in 키워드를 통해 함수의 구현과 리턴형/파라미터를 구분합니다. 리턴형과 파라미터는 다시 ->로 구분됩니다.

위의 코드와 같이 파리미터나 리턴값의 자료형을 추론할 수 있는 경우라면, 다음과 같이 코드를 더욱 간략하게 작성할 수도 있습니다.

 

Class

클래스를 선언할 때는 class 키워드를 사용합니다. 속성과 메소드를 선언하는 방식은 앞에서 설명한 내용과 동일합니다. 

인스턴스를 생성할 때는 클래스 이름 뒤에 괄호를 적어줍니다. 인스턴스를 생성하는 Java 문법에서 new와 세미콜론(;)이 빠진 형태라고 보시면 쉽게 이해하실 수 있을 것입니다.
인스턴스의 멤버에 접근하거나 메소드를 호출할 때는 많은 언어에서 사용하고 있는 dot syntax를 사용합니다.

기본 초기화 메소드의 이름은 init이고, 인스턴스 자신을 나타내는 키워드는 Objective-C와 동일한 self입니다.

Objective-C에서 dealloc 메소드를 통해 리소스를 정리하는 작업은 Swift의 deinit 메소드를 통해 수행할 수 있습니다.

Objective-C에서는 하위 클래스를 생성할 때, 반드시 상속할 클래스를 지정해 주어야 했지만 Swift에는 이러한 제약이 없기 때문에 생략할 수 있다.
서브클래싱 문법은 Objective-C와 동일합니다.

상위 클래스의 구현을 재정의하는 메소드의 경우 반드시 override 키워드를 통해 재정의 되었다는 것을 표시해 주어야 합니다.
Swift에서는 override 키워드 없이 재정의된 메소드와 override 키워드를 사용했지만 상위 클래스에 동일한 메소드가 없는 경우 모두 오류로 판단합니다.

아래의 코드와 같이 변수 선언에 이어지는 { } 내에서 getter와 setter를 구현할 수도 있습니다.

C#에서 setter를 구현할 때 새로운 값이 value라는 키워드로 표현되는 것처럼, Swift의 setter는 newValue라는 키워드로 새로운 값을 표현합니다.

willSet, didSet 블록을 사용하면 값을 설정하기 전이나 설정한 후에 원하는 추가 작업을 수행할 수 있습니다.

 

Enumeration

열겨형은 enum 키워드를 통해 생성하며, 클래스와 마찬가지로 메소드를 가질수도 있습니다.
아래의 코드에서는 Int형의 열거형을 선언하고 있지만, 문자열이나 부동소수점 자료형을 사용하여 열거형을 선언할 수도 있습니다.

열거형의 원래 값(raw value)과 열겨형 값(enumeration value)을 상호 변환할 때는 toRaw, fromRaw 함수를 사용합니다.

 

Struct

구조체를 생성할 때는 struct 키워드를 사용하며, 클래스와 유사한 기능을 제공합니다.

 

Protocol

프로토콜을 선언할 때는 protocol 키워드를 사용합니다.

Swift에서는 클래스, 열거형, 구조체가 프로토콜을 채용(adopt) 할 수 있습니다.

mutating 키워드는 구조체를 변경하는 함수를 표시하는데 사용됩니다.

 

Extension

Objective-C의 카테고리, 클래스 익스텐션과 유사한 기능을 구현하기 위해서는 extension 키워드를 사용합니다. Objective-C에서는 메소드만 추가하는 방식이었지만, Swift의 extension은 메소드와 속성을 함께 추가하여 기능을 확장할 수 있습니다.

 

Generics

Swift는 다른 유명한 프로그래밍 언어에서 지원하는 일반화 프로그래밍을 지원하면, 구현 방식 역시 매우 유사합니다.

 

여기까지 읽어보신 후, Swift에 대해 어떠한 생각을 가지게 되셨나요? 정말 Objective-C를 넘어서는 언어가 될 수 있을까요? 더 나아가 앱과 웹을 아우르는 멋진 언어가 될 수 있을까요?
앞으로 어느정도의 시간이 걸릴지는 모르겠지만 각 주제에 대해서 제가 공부한 내용을 정리해서 공유할 생각입니다.
새로운 언어를 공부하는 iOS & Mac 개발자 분들께 도움이 되기를 바라며, 잘못된 내용이나 부족한 내용이 있으시다면 메일이나 코멘트를 통해 알려주시면 감사하겠습니다. :)

 

ps. Facebook 페이지에 가입해서 함께 정보를 공유해보아요 :)   https://www.facebook.com/groups/254425194763076/

Filed under: Swift

  1. 최일준
    감사합니다. 너무 많은 도움을 받고 갑니다.
  2. 플라인
    강의 감사드립니다. 잘보고겠습니다. 아래와 같은 내용이 잘못된거 같아 댓글남깁니다. [Format String] let apples = 3 let oranges = 5 let appleSummary = "I have (apples) apples." let fruitSummary = "I have (apples + oranges) pieces of fruit. 위 내용이 잘못된거 같습니다.(오류 발생) 이스케이프 문자가 소괄호 앞에 있어야 되는거 같습니다 let appleSummary = "I have \(apples) apples." let fruitSummary = "I have \(apples + oranges) pieces of fruit."

  3. Warning: printf() [function.printf]: Too few arguments in /www/meetkei_com/wordpress/wp-content/themes/Sparrow/functions.php on line 549
    […] http://meetkei.com/?p=3250 […]
  4. 아 정말 매번 찾아와서 팁들 스크랩 하는데 이건 댓글을 안 달고 갈 수가 없네요. 고맙습니다.
    • Kei
      도움이 되셨길 바랍니다^^