코드를 작성하면서 자주 사용했던 연산자(+, -, * 등)들은 사실 메서드로 이루어져 있습니다.
대표적인 예로 문자열의 덧셈을 확인해보면 알 수 있습니다.
✅ 문자열의 덧셈(+) 연산자 메서드
문자열끼리 더하는 덧셈 연산자는
static func + (lhs: String, rhs: String) -> String
으로 이루어진 메서드입니다.연산자 메서드는 일반 메서드(함수)와는 조금 다른 실행 형태를 가지고 있습니다.
일반적인 메서드(함수)는함수 이름(파라미터: 타입)
의 형태로 실행되지만, 연산자 메서드의 경우에는 연산자 이름(기호)만을 사용하여 실행합니다.var a = "hello" var b = " kim" //var c = String.+(lhs: a, rhs: b) 연산자 메서드는 이러한 형태로 실행하지 않습니다. var c = a + b print(c) // hello kim
연산자 메서드가 구현되지 않은 타입은 개발자가 직접 구현하여 사용할 수 있습니다.
✅ 특정 타입의 연산자 메서드 구현
연산자 메서드를 구현할 때는 확장(extension)을 통해 정의하거나 해당 타입에 직접 정의하면 됩니다.
struct Vector3D{ var x = 0.0 var y = 0.0 var z = 0.0 } extension Vector3D{ static func +(lhs: Vector3D, rhs: Vector3D) -> Vector3D{ return Vector3D(x: lhs.x + rhs.x, y: lhs.y + rhs.y, z: lhs.z + rhs.z) } } var A_3D = Vector3D(x: 1.0, y: 2.0, z: 3.0) var B_3D = Vector3D(x: 10.0, y: 20.0, z: 30.0) var C_3D = A_3D + B_3D print(C_3D) // Vector3D(x: 11.0, y: 22.0, z: 33.0)
✅ 특정 타입의 전치(prefix) 연산자 메서드 구현
특정 변수 또는 값 앞에 연산자를 붙여 사용하는 연산자를 전치(prefix)연산자라 부릅니다.
전치(prefix)연산자 메서드를 구현할 때는
static func
코드 사이에prefix
키워드를 추가해야 합니다.struct Vector3D{ var x = 0.0 var y = 0.0 var z = 0.0 } extension Vector3D{ static prefix func -(vector: Vector3D) -> Vector3D{ return Vector3D(x: -vector.x, y: -vector.y, z: -vector.z) } } var A_3D = Vector3D(x: 1.0, y: 2.0, z: 3.0) print(-A_3D) // Vector3D(x: -1.0, y: -2.0, z: -3.0)
✅ 특정 타입의 복합할당 연산자 메서드 구현
복합할당 연산자의 경우 내부에서 덧셈(+), 뺄셈(-) 연산이 필요하기 때문에 해당 연산자를 미리 정의해야 합니다.
struct Vector3D{ var x = 0.0 var y = 0.0 var z = 0.0 } extension Vector3D{ static func +(lhs: Vector3D, rhs: Vector3D) -> Vector3D{ return Vector3D(x: lhs.x + rhs.x, y: lhs.y + rhs.y, z: lhs.z + rhs.z) } static func +=(lhs: inout Vector3D, rhs: Vector3D){ lhs = lhs + rhs } } var A_3D = Vector3D(x: 1.0, y: 2.0, z: 3.0) A_3D += A_3D print(A_3D) // Vector3D(x: 2.0, y: 4.0, z: 6.0)
비교 연산자는 동일성 비교와 크기 비교가 있습니다.
Swift에서 동일성 비교 연산자(==, !=)를 구현하기 위해서는 Equatable 프로토콜을 채택해야 하며, 크기 비교 연산자(<, >, <=, >=)의 경우에는 Comparable 프로토콜을 채택해야 합니다.
✅ 특정 타입의 동일성 비교 연산자 메서드 구현
구조체의 경우 저장속성만 가지고 있으면서 해당 저장속성의 타입이 Equatable 프로토콜을 준수할 경우 별다른 메서드 정의없이 바로 비교 연산자를 사용할 수 있습니다.
struct Vector3D{ var x = 0.0 var y = 0.0 var z = 0.0 } extension Vector3D: Equatable{ } var A_3D = Vector3D(x: 1.0, y: 2.0, z: 3.0) var B_3D = Vector3D(x: 10.0, y: 20.0, z: 30.0) print(A_3D == B_3D) // false
✅ 특정 타입의 크기 비교 연산자 메서드 구현
크기 비교 연산자의 경우 작다(<) 연산자 1개만 정의해도 나머지 크기 비교 연산자(>, <=, >=)를 전부 사용할 수 있습니다.
struct Vector3D{ var x = 0.0 var y = 0.0 var z = 0.0 } extension Vector3D: Comparable{ static func <(lhs: Vector3D, rhs: Vector3D) -> Bool{ return (lhs.x < rhs.x) && (lhs.y < rhs.y) && (lhs.z < rhs.z) } } var A_3D = Vector3D(x: 1.0, y: 2.0, z: 3.0) var B_3D = Vector3D(x: 10.0, y: 20.0, z: 30.0) print(A_3D < B_3D) // true print(A_3D <= B_3D) // true print(A_3D > B_3D) // false print(A_3D >= B_3D) // false
✅ 사칙 연산자 구현
static func +(lhr: 타입, rhs: 타입) -> 반환 타입{ return 코드 구현 }
✅ 전치 연산자 구현
전치 연산자를 구현할 때는 prefix 키워드를 func 앞에 작성해야 합니다.
static prefix func -(xxx: 타입) -> 반환 타입{ return 코드 구현 }
✅ 복합할당 연산자 구현
복합할당 연산자를 구현할 때는 inout 키워드를 사용해야 하며, 덧셈(+) 또는 뺄셈(-) 메서드가 사전에 정의되어야 합니다.
static func +=(lhr: inout 타입, rhs: 타입){ 코드 구현 }
✅ 동일성 비교 연산자 구현
동일성 비교 연산자 메서드를 구현하기 위해서는 Equatable 프로토콜을 꼭 채택해야 합니다.
커스텀 타입에 따라 구현하는 방법이 조금씩 다릅니다.static func ==(lhr: 타입, rhs: 타입) -> Bool{ return 코드 구현 }
✅ 크기 비교 연산자 구현
크기 비교 연산자 메서드를 구현하기 위해서는 Comparable 프로토콜을 꼭 채택해야 합니다.
크기 비교 연산자의 경우 작다(<) 연산자 1개만 정의해도 나머지 크기 비교 연산자(>, <=, >=)를 전부 사용할 수 있습니다.static func <(lhr: 타입, rhs: 타입) -> Bool{ return 코드 구현 }