C 언어 등 기존 언어에서의 연선자는 연산자 우선순위를 쉽게 알기 어려웠다.
그러나 스위프트에서는 연산자 우선순위 를 지정해 놓았기 때문에 코딩하다가 헷갈리는 경우를 확인하면 된다.
우선순위가 높은 연산자는 자신에 비해서 우선순위가 낮은 연산자보다 먼저 실행된다.
프로그래머가 임의로 정의하는 사용자 정의 연산자 또한 이 규칙에 따라 실행 순서가 결정된다.
또, 연산자가 연산하는 결합방향(Associativity)도 지정되어 있다.
결합방향은 같은 우선순위에 있는 연산자끼리 나열되었을 때 어느 방향부터 그룹지을 것인지 나타낸다.
예를 들어 1 + 2 + 3 + 4
라는 수식이 있다면, 연산자 + 는 모두 같은 우선도를 가지며 +의 결합방향은 왼쪽이기 때문에 (((1 + 2) + 3) + 4)
처럼 왼쪽부터 그룹이 묶이는 것이다.
// 스위프트 표준 라이브러리 연산자 정의 중 일부
infix operator === : ComparisonPrecedence
infix operator ~= : ComparisonPrecedence
infix operator &= : AssignmentPrecedence
infix operator % : MultiplicationPrecedence
기본 연산자들의 우선도와 결합방향을 알아보려면 스위프트 표준 라이브러리의 연산자 정의를 참고 하면 된다.
하지만, 위의 코드를 아무리 둘러봐도 연산자 우선도와 결합방향을 알 수 없다. 연산자 뒤에 콜론을 붙이고 이어서 써준 연산자 우선순위 그룹(precedencegroup)을 지정해준 것이기 때문이다.
스위프트 표준 라이브러리에는 다양한 우선순위 그룹이 존재한다.
// 스위프트 표준 연산자 우선순위 그룹 중 일부
precedencegroup BitwiseShiftPrecedence {
higherThan: MultiplicationPrecedence
}
precedencegroup FunctionArrowPrecedence {
associativity: right
higherThan: AssignmentPrecedence
}
precedencegroup TernaryPrecedence {
associativity: right
higherThan: FunctionArrowPrecedence
}
precedencegroup LogicalDisjunctionPrecedence {
associativity: left
higherThan: TernaryPrecedence
}
위 코드처럼 연산자 우선순위 그룹은 higherThen, lowerThen, associativity 등으로 우선순이 및 결합방향 등을 지정한 것을 볼 수 있다.
연산자 우선순위 그룹의 정의를 보면 스위프트 연산자 우선순위는 절대치가 아닌 상대적인 수치임을 알 수 있다.
스위프트 표준 라이브러리의 연산자 우선순위 그룹 우선순위별 정렬(우선순위 높은 순)
연산자 우선순이가 높을수록 같은 라인의 연산자 중 먼저 처리된다.
import Foundation
let intValue: Int = 1
let resultValue1: Int = intValue << 3 + 5 // 3 + 5 => 13
let resultValue2: Int = 1 * 3 + 5 // 3 + 5 => 8
위 코드에는 Int 타입의 피연자를 연산하기 위해 << , +, * 연산을 사용했다.
Int 타입의 << 연산은 BitwiseShiftPrecedence
연산자 우선순위 그룹을 우선순위로 가지며,
AdditionPrecedence
연산자 우선순위 그룹을 우선순위로 가진다. 따라서 << 연산이 + 연산보다 더 먼저 실행되는 것을 확인할 수 있다.
또, * 연산은 MultiplicationPrecedence
연산자 우선순위 그룹을 우선순위로 가지므로 + 연산보다 먼저 실행된다.
오늘은 5 단원 2번째 인 연산자 우선순위와 결합방향을 공부했다.