스위프트의 연산자는 특정한 문자로 표현한 함수, 따라서 특정 연산자의 역할을 프로그래머의 의도대로 변경할 수 있다.
다른 언어와 유사한 연산자에 대한 설명은 생략하였다.
1. 연산자의 분류
분류 | 설명 | 예시 |
단항 연산자 | 피연산자가 한 개인 연산자 | !A |
이항 연산자 | 피연산자가 두 개인 연산자 | A + B |
삼항 연산자 | 피연산자가 세 개인 연산자 | A ? B : C |
전위 연산자 | 연산자가 피연산자 앞에 위치하는 연산자 | !A |
중위 연산자 | 연산자가 피연산자 사이에 위치하는 연산자 | A + B |
후위 연산자 | 연산자가 피연산자 뒤에 위치하는 연산자 | A! |
❗스위프트는 띄어쓰기도 중요한 언어. A != B 와 A! = B는 전혀 다른 의미이며 A > B? A : B 와 같이 사용하면 오류가 발생한다.
A > B ? A : B와 같이 정확하게 사용해야 한다.
2. 연산자의 종류
2-1. 산술, 비교 연산자
연산자 | 부호 | 설명 및 예시 |
대입 연산자 | A = B | A에 B의 값을 대입, 서로 다른 데이터 타입일 경우 오류 발생 |
나누기 연산자 | A / B | A를 B로 나눈 값을 리턴, ex) 11 / 3 → 3 |
나머지 연산자 | A % B | A를 B로 나눈 나머지 리턴, ex) 11 % 3 → 2 |
참조 비교 연산자 | A === B | A와 B가 참조(레퍼런스) 타입일 때, A와 B가 같은 인스턴스를 가리키는지 비교 |
참조 비교 연산자 | A !== B | A와 B가 참조(레퍼런스) 타입일 때, A와 B가 같지 않은 인스턴스를 가리키는지 비교 |
패턴 매치 연산자 | A ~= B | A와 B의 패턴이 매치되는지 확인 |
❗스위프트에서는 다른 언어와 달리 부동소수점 타입의 나머지 연산도 지원한다.
2-2. 범위 연산자
연산자부호설명 및 예시
연산자 | 부호 | 설명 및 예시 |
폐쇄 범위 연산자 | A...B | A부터 B까지의 수를 묶어 범위를 표현 |
반폐쇄 범위 연산자 | A..<B | A부터 B미만의 수를 묶어 범위를 표현 |
단방향 범위 연산자 | A... ...A ..<A |
A 이상의 수를 묶어 범위를 표현 A 이하의 수를 묶어 범위를 표현 A 미만의 수를 묶어 범위를 표현 |
2-3. 기타 연산자
- 오버플로 연산자 : 스위프트는 연산자를 통해 오버플로에 대비할 수 있도록 하였다.
연산자 | 부호 | 설명 및 예시 |
오버플로 더하기 연산 | &+ | 오버플로에 대비한 덧셈 연산 |
오버플로 빼기 연산 | &- | 오버플로에 대비한 뺄셈 연산 |
오버플로 곱하기 연산 | &* | 오버플로에 대비한 곱셈 연산 |
nil 병합 연산자 | A ?? B | A가 nil이 아니면 A를 반환하고 nil이면 B를 반환 |
부호 변경 연산자 | -A | A(수)의 부호를 변경 |
옵셔널 강제 추출 연산 | O! | O(옵셔널 개체)의 값을 강제로 추출 |
옵셔널 연산자 | V? | V(옵셔널 값)을 안전하게 추출하거나, V(데이터 타입)가 옵셔널임을 표현 |
3. 연산자 우선순위와 결합방향
C언어 등의 기존 언어에서는 연산자 우선 순위를 알기 어려웠다. 하지만, 스위프트에서는 연산자 우선순위를 지정해 놓았기 때문에 코딩을 하다가 헷갈리면 확인하면 된다. 우선순위가 높은 연산자는 낮은 연산자보다 먼저 실행된다. 사용자 정의 연산자 또한 이 규칙에 따라 실행 순서가 결정된다.
또, 연산자가 연산하는 결합방향도 지정되어 있다. 결합방향은 같은 우선 순위에 있는 연산자끼리 나열되어있을 때 어느 방향부터 그룹지을 것인지 나타낸다.
아래는 스위프트 표준 라이브러리에 정의된 연산자 정의의 일부이다.
infix operator === : ComparisonPrecedence
infix operator ~= : ComparisonPrecedence
infix operator % : MultiplicationPrecedence
infix operator %= : AssignmentPrecedence
...
연산자 정의는 연산자와 연산자 우선순위 그룹을 지정하여 정의된다.
아래는 연산자 우선순위 그룹의 일부와 우선순위별 정렬표이다.
precedencegroup BitwiseShiftPrecedence {
higherThan: MultiplicationPrecedence
}
precedencegroup FunctionArrowPrecedence {
associativity: right
higherThan: AssignmentPrecedence
}
...
연산자 우선순위 그룹 이름 | 결합 방향 | 할당 방향 사용 |
DefaultPrecedence | none | false |
BitwiseShiftPrecedence | none | false |
MultiplicationPrecedence | left | false |
AdditionPrecedence | left | false |
RangeFormationPrecedence | none | false |
CastingPrecedence | none | false |
NilCoalescingPrecedence | right | false |
ComparisonPrecedence | none | false |
LogicalConjunctionPrecedence | left | false |
LogicalDisjunctionPrecedence | left | false |
TernaryPrecedence | right | false |
AssignmentPrecedence | right | true |
FunctionArrowPrecedence | right | false |
예시)
let intValue: Int = 1
let resultValue1: Int = intValue << 3 + 5
let resultValue2: Int = 1 * 3 + 5
resultValue1에서는 비트 연산자가 우선순위가 높으므로 0001 에서 3비트 옮겨진 8이 5와 더해져 13이 된다.
resultValue2에서는 곱셈 연산자가 우선순위가 높으므로 8이 된다.
4. 사용자 정의 연산자
스위프트에서는 프로그래머가 연산자 역할을 부여할 수 있으며 기존에 존재하지 않던 연산자 기호를 만들어 추가할 수도 있다. 앞서 보았던 infix 키워드는 중위 연산자를 의미하고 prefix, postfix는 각각 전위 연산자, 후위 연산자를 의미한다. 또한, operator 키워드는 연산자임을 나타내고 associativity는 연산자 결합방향, precedence는 우선순위를 나타낸다.
4-1. 전위 연산자 정의와 구현
Int 타입의 제곱을 구하기 위해 **를 전위 연산자로 사용하려 한다. 구현은 다음과 같다.
prefix operator **
prefix func ** (value: Int) -> Int {
return value * value
}
다른 예시로, 정수에 사용되는 ! 연산자를 문자열이 비어있는지 확인하기 위한 전위 연산자로 사용하려한다.
prefix func ! (value: String) -> Bool {
return value.isEmpty
}
4-2. 후위 연산자 정의와 구현
이번에는 **를 붙이면 10이 더해지는 후위 연산을 구현해본다.
postfix operator **
postfix func ** (value: Int) -> Int {
return value + 10
}
만약, 후위 연산자와 전위 연산자가 둘 다 구현되어 있고 **num**와 같이 한 번에 사용되면 후위 연산을 먼저 실행한다.
4-3. 중위 연산자 정의와 구현
중위 연산자도 크게 다르지 않지만, 전위 연산자나 후위 연산자와 달리 우선순위 그룹을 명시할 수 있다. 만약 우선순위 그룹을 정의해주지 않는다면 우선순위가 가장 높은 DefaultPrecedence를 갖게 된다. 아래는 오른쪽 문자열이 왼쪽 문자열에 속해 있는지 확인하는 연산을 구현한 것이다.
import Foundation
// String의 contains(_:) 메소드를 사용하기 위해
infix operator ** : MultiplicationPrecedence
func ** (lhs: String, rhs: String) -> Bool {
return lhs.contains(rhs)
}
'앱 > iOS' 카테고리의 다른 글
Swift - ARC (0) | 2022.01.31 |
---|---|
Swift - 모나드 (0) | 2022.01.22 |
iOS - 객체 제어 (0) | 2021.11.07 |
iOS와 코코아 터치 프레임워크 (0) | 2021.11.06 |
iOS 앱의 구조 (0) | 2021.11.05 |