CLOSE SEARCH

Swift – Operators && Operator Function

Swift에서는 Objective-C에서 제공했던 대부분의 표준 연산자들을 제공합니다. 한발 더 나아가, 그동안 연산자들을 사용하면서 자주 발생하는 실수들을 사전에 방지할 수 있는 다양한 기능들을 제공합니다. 그리고 기본 연산자의 동작을 재정의하거나 +++ 와 같은 새로운 연산자를 만들어서 사용할 수 있도록 해줍니다.

할당 연산자(=)

할당 연산자는 변수의 값을 초기화 하거나 하나의 변수에 다른 변수의 값이나 상수 등을 할당하는데 사용하는 연산자 입니다. 할당 연산자를 사용하는 문법은 Objective-C와 동일하지만, 앞으로 설명할 두개의 내용을 주목해 볼 필요가 있습니다.
먼저, Swift에서 새롭게 도입된 튜플의 초기값을 설정하거나 다른 튜플의 값을 할당할 때에는 코드 1-1에서 보여주는 문법을 사용합니다.

그리고 조건 비교식에서 == 을 =으로 잘못써서 발생되는 논리적 오류를 사전에 방지하기 위해서 대입 연산은 결과를 반환하지 않도록 변경되었습니다. Objective-C에서 코드 1-2와 같이 if 문의 조건식 부분을 실수로 width = height로 작성했다고 가정해 봅시다.

= 연산자를 사용했기 때문에 width 변수에는 height 변수의 값이 할당되고, 연산의 결과가 0이 아닌 값이 되고, 0이 아닌 값은 참으로 평가되므로, 결과적으로 if문 안의 코드가 실행됩니다. 원래 의도는 너비와 높이가 같은 경우에만 코드를 수행하는 것이었기 때문에 이것은 논리적인 오류입니다. 이러한 오류를 줄이기 위해서 Swift에서는 = 연산자가 연산 결과를 리턴하지 않는 것입니다. 실제로 코드 1-3과 같이 조건 비교식에서 = 를 사용하는 경우에는 Objective-C와 달리 오류로 인식되고 컴파일을 할 수 없게 됩니다.

 

산술 연산자

Swift의 산술 연산자는 C나 Objective-C의 산술 연산자와 기호나 문법적인 측면에서는 동일합니다. 하지만, 산술 연산의 결과가 오버플로우 되는 것을 허용하지 않는다는 사실을 기억해 두어야 합니다. C에서는 오버플로우를 유발할 수 있는 코드가 있는 경우 컴파일 시점에 이러한 오류를 발견하기 쉽지 않았고, 런타임에 발견했다고 하더라도 완변하게 디버깅 하는 것은 어렵고 귀찮은 작업이었습니다. 그러나 Swift는 오버플로우 자체를 오류로 판단하고 컴파일 시점에 알려줍니다. 만약, 이전처럼 오버플로우 허용하고자 한다면, 새로 도입된 Overflow Operator를 사용할 수 있습니다. 오버플로우 연산자에 대해서는 뒤에서 다시 설명하겠습니다.

Swift의 + 연산자는 문자열을 연결하는 기능도 제공하므로 Objective-C에 비해 간편하게 문자열을 연결할 수 있게 되었습니다.

 

나머지 연산자(%)

Swift의 나머지 연산자는 정수 뿐만 아니라 부동수소점 수에 대한 나머지 연산도 지원합니다. 연산의 결과는 Double 형으로 리턴됩니다.

 

복합 할당 연산자(+=, -=, *= 등)

복합 할당 연산자는 Objective-C와 동일한 문법으로 사용할 수 있지만, 할당 연산자에서 설명했던 것과 같이 연산의 결과를 리턴하지 않기 때문에 조건 표현식 등에서 사용할 수 없다는 것을 기억해 두어야 합니다.

 

비교 연산자

비교 연산자 역시 C, Objective-C와 동일한 문법을 사용합니다. Swift에서는 두개의 참조가 동일한 인스턴스를 가리키고 있는지 비교하는데 사용할 수 있는 두개의 identity operator(===, !==)를 제공합니다.

 

범위 연산자(…, ..)

Swift에서는 반복문에서 반복의 범위를 지정하는데 사용할 수 있는 새로운 범위 연산자를 제공합니다. 점 3개로 표현되는 … 연산자는 closed range operator라고 부르며 연산자의 좌항에서 우항까지의 범위를 표현하는데 사용됩니다. 코드 4-1과 같이 0…5의 범위는 0에서 5까지이므로 for 문은 총 6번 실행됩니다.

점 2개로 표현되는 .. 연산자는 half-closed range operator라고 부르며 연산자의 좌항에서 우항 – 1 까지의 범위를 표현합니다. 코드 1-0과 동일한 코드를 half-closed range operator를 사용하도록 변경하면 for 문이 총 5번 실행됩니다.

 

오버플로우 연산자

앞서 설명했던 것과 같이, Swift의 산술 연산자는 기본적으로 오버플로우를 허용하지 않습니다. 오버플로우 연산자는 C와 같이 오버플로우를 허용해야 하는 경우에 사용할 수 있는 새로운 연산자 입니다. 이 연산자는 기존 산술 연산자 앞에 &가 붙은 형태를 띄고 있습니다. Swift에서는 다섯개의 오버플로우 연산자를 제공합니다.

Overflow addition (&+)
Overflow subtraction (&-)
Overflow multiplication (&*)
Overflow division (&/)
Overflow remainder (&%)

 

앞에서 별도로 설명하지 않은 증가 연산자(++), 감소 연산자(—), 단항 더하기 연산자(+), 단항 빼기 연산자(-), 삼항 연산자( ? : ), 논리 연산자(!, && ||), 비트 연산자(|, &, ^, <<, >>) 는 C, Objective-C와 동일한 문법으로 사용할 수 있습니다.

 

연산자 오버로딩

Swift는 연산자 오버로딩을 지원합니다. Objective-C를 사용하면서 가장 아쉬운 점이 연산자를 재정의 할 수 없다는 것이었는데, 개인적으로 가장 반가운 기능이기도 합니다. Swift에서는 연산자 오버로딩을 Operator Function이라는 용어로 부릅니다. 먼저 기본적으로 제공되는 연산자를 재정의 하는 방법을 살펴보겠습니다.

코드 5-1은 Vector2D 구조체의 선언과 이 구조체를 대상으로하는 + 연산자 함수의 구현을 보여줍니다. 함수를 선언하는 문법과 유사하며, func 키워드 앞에 @infix 키워드(또는 한정자-Qualifier)를 붙이고 함수의 이름을 적는 부분에 재정의 할 연산자를 적어주면 됩니다. @infix라는 키워드가 Swift의 연산자 오버로딩을 이해하는데 핵심이 되는 것입니다. 실제로 Swift에는 @infix 뿐만 아니라 @prefix, @postfix, @assignment라는 연산자 오버로딩 관련 키워드가 제공됩니다.

먼저 @infix는 이항 연산자를 재정의 하는데 사용되는 키워드 입니다. 코드 2-0에서 재정의하는 + 연산자가 두개의 값을 더하는 이항 연산을 수행하기 때문에 @infix 키워드를 붙였던 것입니다. 아래와 같이 비교 연산자를 재정의 하는 경우에도 @infix를 사용합니다.

@prefix, @postfix 키워드는 단항 연산자와 관련이 있습니다. 이름에서 알수 있듯이, @prefix는 전위 연산자를 재정의 하는데 사용되고, @postfix는 후위 연산자를 재정의 하는데 사용됩니다. 코드 5-1에서 보여준 Vector2D 구조체의 값을 음수로 변경하도록 – 단항 연산자를 재정의한 코드는 다음과 같습니다.

마지막으로 @assignment 키워드는 할당과 관련된 연산자들을 재정의 하는데 사용되는 키워드 입니다. 이러한 연산자들을 재정의 할 때는 두가지 사항을 반드시 기억해두어야 합니다. = 연산자는 재정의 할 수 없으며, 아래의 코드와 같이 왼쪽 파리미터는 반드시 inout 키워드를 사용해서 선언해야 합니다. inout 키워드는 해당 파라미터가 연산자 함수의 구현 내부에서 값이 변경된다는 것을 나타냅니다.

증가 연산자(++)나 감소 연산자(—)는 @assignment 키워드와 @prefix, @postfix 중 하나의 조합으로 재정의 할 수 있습니다. Vector2D 구조체의 모든 값을 1씩 증가시키도록 ++ 연산자를 재정의한 코드는 아래와 같습니다.

Swift에서 제공하는 대부분의 기본 연산자들을 재정의 할 수 있지만, = 연산자와 삼항 연산자는 재정의 할 수 없습니다.

만약 앞에서 설명한 기본 연산자 재정의로 원하는 기능을 구현할 수 없다면, 아래의 문자들을 조합하여 새로운 연산자를 선언할 수도 있습니다. Swift에서는 이러한 연산자를 Custom Operator라고 부릅니다.

/ = – + * % < > ! & | ^ . ~

기본 연산자와 달리 사용자 정의 연산자는 전역 범위에서 연산자를 선언해 주어야 합니다. 즉, 구현과 별도로 선언문이 필요합니다. 선언문에서는 4개의 키워드가 사용됩니다. operator 키워드는 연산자를 선언하는 역할을 하고, prefix, infix, postfix는 연산자의 위치(즉 전위, 중위, 후위)를 지정하는 역할을 합니다. 다음은 +++를 새로운 연산자로 선언하고, Vector2D의 각 값을 2배씩 증가시키도록 구현한 코드입니다.

사용자 정의 연산자(infix)를 구현하는 경우에는 연산자의 우선순위에 유의해야 합니다. Swift에서는 Auto Layout처럼 연산자에도 우선순위(Priority)를 지정할 수 있습니다. 기본 우선 순위값은 100이고, 새로운 우선순위를 지정하려면 연산자를 선언할 때 다음과 같이 { } 사이에 우선 순위와 관련된 정보를 제공해야 합니다.

associativity 키워드와 조합할 수 있는 키워드에는 left, right, none이 있고, none은 기본값으로 생략할 수 있습니다. precedence는 우선순위를 지정하는 역할을 하는 키워드이고 기본값(100)으로 설정하는 경우 뒤의 숫자를 생략할 수 있습니다.

 

 

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

이 글의 예제 코드는 다음에서 발췌하였습니다: Apple Inc. ‘The Swift Programming Language.’ iBooks. https://itun.es/kr/jEUH0.l

Filed under: Swift

  1. 닥서클
    범위 연산자부분이 잘못된거 같습니다 for i in 0..3 { println (i) } 아래와 같이 변경된거 같네요. for i in 0..<3 { println (i) }