SWIFT

[Swift] 연산자 메서드와 사용자 정의 연산자

clamp 2023. 4. 19. 12:52

연산자 메서드

struct Vector2D{
    var x = 0.0
    var y = 0.0
}

let vector1 = Vector2D(x: 3.0, y: 1.0)
let vector2 = Vector2D(x: 1.0, y: 0.5)

extension Vector2D{
    // static(타입)메서드인 이유는 서로 다른 인스턴스를 더하기 때문에 타입 메서드이다.
    // 중위연산자⭐️(infix)는 생략이 가능하다
    static func + (lhs: Vector2D, rhs: Vector2D) -> Vector2D{
        return Vector2D(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
    }
    
    // let plusVector = vector1 + vector2
    
    static func - (lhs: Vector2D, rhs: Vector2D) -> Vector2D{ // 중위연산자(infix)는 생략이 가능하다
        return Vector2D(x: lhs.x - rhs.x, y: lhs.y - rhs.y)
    }
    
    //let negativeVector = vector1 - vector2
    
    // -----------------------------------------------------------
    
    // 전위 연산자⭐️
    static prefix func - (vector: Vector2D) -> Vector2D{
        return Vector2D(x: -vector.x, y: -vector.y)
    }
    
    // let negativeVector = -vector1
    
    // -----------------------------------------------------------
    
    // 복합할당 연산자⭐️
    // 이 전에 구현한 infix연산자를 활용
    static func += (lhs: inout Vector2D, rhs: Vector2D) -> Vector2D{
        return lhs + rhs
    }

사용자 정의 연산자

// 중위연산자가 아닌 경우⭐️

//1) 사용하려는 연산자의 선언

postfix operator ++     // 기존에 정의되어있는 연산자들은 사용 불가하다.

extension Int{
    static postfix func ++ (number: inout Int){
        number += 1
    }
}

var i = 0

i++ // 1

사용자 정의 중위 연산자⭐️ 

1. 중위 연산자는 우선순위 그룹이 선언되어야 한다. 우선순위를 설정하는 이유는 각 연산자마다 우선순위가 다르기 때문이다.

// 새롭게 생성한 우선순위그룹 UserPrecedence

precedencegroup UserPrecedence{
    higherThan: AdditionPrecedence  //더하기 우선순위 그룹보다 우선순위가 높다
    lowerThan: MultiplicationPrecedence  // 곱하기 우선순위 그룹보다 우선순위가 낮다.
    associativity: left         // 결합성을 의미, 결합 방향을 의미한다
}

* 결합방향

20 - 10 - 2 라는 식이 존재할경우 우리는 이렇게 왼쪽부터 계산한다.

20 - 10 = 10 - 2 =  8     이런 식으로 왼쪽에서부터 오른쪽으로 결합해나간다.

이게 바로 left 결합방향이다.

 

반대로 right 결합방향을 사용해보면,

2 - 10 = - 8 - 20 = -28 다른 결과가 도출된다.

 

-2 - 10 = -12 + 20 = 8 아니냐 라고 할 수 있지만..

left방식으로 바꿔보면 

2 - 10 - 20 이렇게 되기 때문에 수학적으로 보지말고 단순히 순서로 봐야할 것 같다.

 

2. 연산자의 선언과 우선순위그룹을 지정한다.

infix operator +-: UserPrecedence

전역 범위에서 선언해야한다. 새로운 우선순위 그룹을 사용하거나, 이미 존재하는 우선순위 그룹을 사용하는 것도 가능하다.

우선순위 그룹을 지정하지 않으면 DefaultPrecedence에 속한다.

 

3. 연산자의 내용을 실제 정의한다.

static func +- (lhs: 타입, rhs: 타입) -> 타입{
        return 구현
    }