본문 바로가기
IT공부/IOS개발

스위프트 공부 _ 사용자 정의 연산자

by 놀고싶은 노자 2021. 7. 14.

스위프트에서는 프로그래머의 입맛에 맞게 연산자 역할을 부여할 수 있다. 

기존에 존재하지 않았던 기호를 만들어 추가하는 것도 가능하다. 

이를 통틀어 사용자 정의 연산자라고 부른다. 

다만, = 과 ?: 는 사용자 정의 역할 부여가 불가능 하다.

 

1) 기존의 연산자 역할을 변경, 새로운 역할을 추가하기 위해서는 

기존의 연산자가 전위(!A)인지, 중위(A+B)인지, 후위(B?)인지 알아야 한다. 

* operator : 연산자

* 전위 연산자 : prefix * 중위 연산자 : infix * 후위 연산자 : postfix

* associativity : 결합방향

* precedence : 우선순위

 

2) 사용자 정의 연산자는 아스키 문자를 결합해서 사용한다. 

/ = - + ! * % < > & | ^ ? ~

또한 . 를 사용자 정의 연산자에 사용 가능하다. 

다만, 주의할 점으로는 . 는 맨앞에 사용이 되어야만 연산자로 인식한다. 

.+. O

+.+ X -> +  .+ 로 인식

? 역시 포함할 수 있지만, 자체만으로는 정의가 불가능하다.

! 도 같은 조건으로 표현이 가능하다 단, 전위 연산자는 ?나 !로 시작하는 사용자 정의 연산자 사용이 불가능하다 .

 

 

전위 연산자 정의와 구현

1) 기존에 없던 전위 연산자를 만들고 싶다면 연산자 정의를 먼저 해야 한다.

 

2) 위와 같이 연산자 정의를 한 뒤, 어떤 데이터 타입에 어떤 동작을 할 것인지 함수를 구현해 주어야 한다. 

   전위 연산자 함수를 구현할 때에는 함수 func 키워드 앞에 prefix 키워드를 추가해야한다. 

 

3) 이미 존재하는 전위 연산자에 기능을 추가할 때에는 따로 연산자 정의를 할 필요는 없으며, 중복 정의하면 된다. 

prefix operator **

prefix func ** (value: Int) -> Int {
	return value * value
}

let a = 5;
let b = **a;
print(b) // 25

prefix func ** (value: String) -> String {
	return value+" "+value
}

let a = "a"
let b = **a
print(b) // a a

후위 연산자의 정의와 구현

전위 연산자를 정의하고 구현한 것과 다르지 않다. 

다만, prefix대신에 postfix를 적어주면 된다. 

postfix operator **
postfix func ** (value: Int) -> Int {
	return value * value
}

let a = 5;
let b = a**;
print(b) // 25

* 하나의 피연산자에 전위 연산자와 후위 연산자를 한 줄에 사용하게 되면 후위 연산자를 먼저 연산한다. 

prefix operator **
prefix func ** (value: Int) -> Int {
	return value * value
}
postfix operator **
postfix func ** (value: Int) -> Int {
	return value + 3
}

let a = 5;
let b = **a**;
print(b) // 64 (8*8)

 

중위 연산자의 정의와 구현

중위 연산자 역시 크게 다르지 않지만, 우선순위 그룹을 명시해 줄 수 있다. 

연산자 우선순위 그룹은 중위 연산자에서만 사용이된다. 전위 연산자, 후위 연산자는 결합방향 및 우선순위를 지정하지 않는다. 

중위 연산자를 정의할 때 우선순위 그룹을 명시하지 않으먄, 우선순위가 가장 높은 defaultPrecedence그룹을 우선순위 그룹으로 갖게 된다. 

 

구현할 때 함수 앞에 infix를 따로 추가하지 않는다.

import Foundation

infix operator ** : MultiplicationPrecedence

func ** (value1 : String, value2: String) -> Bool {
	return value1.contains(value2)
}

let a = "a"
let abc = "abc"
let check = abc ** a 
print(check) // true