서론
연산자도 이미 구현되어있는 타입 메서드 입니다.
예를면 String타입이나, Int타입 등이 이미 구현되어있는 메서드 입니다.
//String 타입
"Hello" + ", Swift!" // "Hello, Swift!"
//Int 타입
1 + 2 //3
BUT.. 열거형, 클레스, 구조체를 + , - , 나 비교( > , =! , == 등등) 등을 사용하고 싶을 때 직접 정의하여 구현이 가능합니다.
연산자 커스텀 타입은 아래와 같은 특성이 있습니다.
- extension을 통해 특정 연산자의 논리를 정의 가능
- 파라미터명은 보통 lhs 와 rhs로 사용
enum타입(열거형)
enum타입에서 == 타입 메소드 역시 이미 구현되어 있어 별도의 구현이 필요하지 않지만아래 코드에서 + 연산자 메소드를 원시값 + 원시값을 리턴하게 정의했습니다.
enum Weekday:Int {
case mon
case tue
case wed
case thu
case fri
case sat
case sun
}
extension Weekday {
static func + (lhs: Weekday , rhs: Weekday) -> Int {
return (lhs.rawValue + rhs.rawValue)
}
}
Weekday.mon == Weekday.tue //false
Weekday.tue + Weekday.wed //3
또한 논리 구조는 개발자 마음대로 커스텀이 가능합니다.
enum Weekday:Int {
case mon
case tue
case wed
case thu
case fri
case sat
case sun
}
extension Weekday {
static func + (lhs: Weekday , rhs: Weekday) -> Bool {
//리턴타입 수정
return (lhs.rawValue + rhs.rawValue) > 2
}
}
Weekday.tue + Weekday.wed // ture
1. 사칙연산 및 복합할당 연산자
struct Vector2D {
var x = 0.0
var y = 0.0
}
var vector = Vector2D(x: 3.0, y: 1.0)
let vector1 = Vector2D(x: 2.0, y: 4.0)
//let combinedVector = vector + vector1 //컴파일 에러 연산자가 구현되어있지않음
// + 연산자 구현
extension Vector2D {
static func + (lhs: Vector2D , rhs: Vector2D) -> Vector2D {
//파라미터로 Vector2D의 값을 받겠음
return Vector2D(x: lhs.x + rhs.x, y: rhs.y + rhs.y)
//x 값은 첫번째와 두번째 x,y값을 더해서 x,y로 받음
}
}
let combinedVector = vector + vector1 //Vector2D(x: 5.0, y: 5.0)
다른 연산자도 정의 및 사용 가능
// * 연산자
extension Vector2D {
static func * (lhs: Vector2D, rhs: Vector2D) -> Vector2D {
return Vector2D(x: lhs.x * rhs.x, y: lhs.y * rhs.y)
}
}
// - 연산자
extension Vector2D {
static func - (lhs: Vector2D, rhs: Vector2D) -> Vector2D {
return Vector2D(x: lhs.x - rhs.x, y: lhs.y - rhs.y)
}
}
//복합할당 연산자
extension Vector2D {
static func += (lhs: inout Vector2D, rhs: Vector2D) {
lhs = lhs + rhs
}
}
2. == (Equatable) , > , ...
- ==(Equatable) 구현 시 != 연산자는 자동 구현됨
- < 연산자 정의 시 나머지( > , >! 등등) 자동으로 컴파일러가 구현
- Equtable타입을 먼저 정의한 뒤 비교 연산자 구현 가능
struct somePoint {
var pointA = 0.0
var pointB = 0.0
}
var pointA = somePoint(pointA: 1.0, pointB: 2.0)
var pointB = somePoint(pointA: 1.0, pointB: 2.5)
var pointC = somePoint(pointA: 1.0, pointB: 2.5)
pointA > pointB
pointC == pointB
위와 같은 코드가 있을 때 컴파일러는 어떤 기준으로 같아야 하는지, 커야하는지 기준을 모르기 때문에 컴파일 에러가 발생.
즉, 개발자는 컴파일러에게 판단 할 수 있는 기준을 만들어주면 됩니다.
3. perfix, posfix , infix 정의
전치(perfix) , 후치(postfix) , 중위(infix) 연산자도 개발자 마음대로 정의할 수 있으며 다음과 같은 순서로 정의할 수 있습니다.
- 선언: 생략가능
- 정의: 선언한 연산자를 구체적으로 정의
- 사용: 정의한 연산자를 사용
perfix 커스텀
//1. 선언 +++를 perfix연산자로 선안할거야
prefix operator +++
//2. 정의
extension Int {
static prefix func+++(num: inout Int) {
num += 3
}
}
num = 2
+++num //5
postfix 커스텀
var num = 0
num = num + 2
//1. 후치연산자로 ++ 기호를 만들거야~ 라고 선언을 해줌
postfix operator ++
//2. 정의
extension Int {
static postfix func ++(num: inout Int) {
num += 1
}
}
num++ //3
infix 커스텀
struct somePoint {
var pointA = 0.0
var pointB = 0.0
}
var pointA = somePoint(pointA: 1.0, pointB: 2.0)
var pointB = somePoint(pointA: 1.0, pointB: 2.0)
infix operator +-
extension somePoint {
static func +- (lhs: somePoint, rhs: somePoint) -> somePoint {
return somePoint(pointA: lhs.pointA + rhs.pointA, pointB: rhs.pointB - rhs.pointB)
}
}
var pointD = pointA +- pointB
print(pointD) //somePoint(pointA: 2.0, pointB: 0.0)
'🍎swift' 카테고리의 다른 글
제어 흐름 (Control Flow) (0) | 2023.11.21 |
---|---|
text field 바꾸기 (플레이스 홀더, 클리어 버튼) (0) | 2023.04.21 |
Swift - 문자열 다루기 01 (0) | 2023.03.29 |
swift - 제네릭(Generics) (0) | 2023.03.22 |
메모리 관리 (0) | 2023.03.12 |