ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • kotlin operator invoke 로 데이터 검증 하기!
    JAVA 2024. 7. 30. 18:14
    728x90

    상황 설명

    • Price의 경우 0원 생성할 수 없지만, 시작값을 위해서는 1개는 존재 해야 합니다.

    이를 어떻게 처리 할까 고민했었는데 아래와 같은 해법이 있네요.

    코드 구현

    data class Price private constructor (private val value: Double) { // 생성자를 비공개로 처리
        override fun toString() = value.toString()
        operator fun plus(price: Price) = Price(this.value + price.value)
        operator fun times(num: Int) = Price(this.value * num)
        
        companion object {
            val identity = Price(0.0) // 0원 구현 private constructor 이기 때문에 외부에서는 생성 못함 
            // 생성시 호출되는 invoke 함수를 companion으로만 제공 
    	    operator fun invoke(value: Double) = 
                if (value > 0)
                    Price(value)
                else 
                    throw IllegalArgumentException("Price must be positive or null")
    	
        }
    }
    
    fun main() {
        println(Price.identity) // 0.0 출력
        println(Price(5.0) + Price(4.8)) // 9.8 출력
        println(Price(5.0) * 3) // 15.0 출력
        println(Price(-0.0)) // Exception in thread "main" java.lang IllegalArgumentException: Price must be positive or null
    
        println(Price(3.12) * 3.2) // The floating-point literal does not conform to the expected type Int
    
        println(Price(5.0) * Price(4.8)) // Type mismatch: inferred type is Price but Int was expected
    
        println(Price(5.0) - 3) // Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public inline operator fun BigDecimal.minus(other: BigDecimal):
    }
    

    operator plus, times 를 구현해서 위와 같이 사용 할 수 있습니다.

    operator 종류

    산술 연산자

    | 함수 이름 | 연산자 | 설명 | |———–|——–|———-| | plus | + | 더하기 | | minus | - | 빼기 | | times | * | 곱하기 | | div | / | 나누기 | | rem | % | 나머지 연산 |

    예제 코드

    data class Price (private val value: Double) { 
        operator fun plus(price: Price) = Price(this.value + price.value)
        operator fun times(num: Int) = Price(this.value * num)
    }
    fun main() {
        println(Price(5.0) + Price(4.8))
        println(Price(5.0) * 3)
    }
    

    대입 연산자

    함수 이름연산자설명

    plusAssign += 더해서 대입
    minusAssign -= 빼서 대입
    timesAssign *= 곱해서 대입
    divAssign /= 나눠서 대입

    예제 코드

    data class Price(private var value: Double) {
        operator fun plusAssign(price: Price) {
            this.value += price.value
        }
    }
    
    fun main() {
        val p1 = Price(5.0)
        val p2 = Price(4.8)
    
        p1 += p2
    
        println(p1) // Output: Price(value=9.8)
    }
    

    단항 연산자

    함수 이름연산자설명 - object가 변수명

    unaryPlus + +object
    unaryMinus - -object
    not ! !object
    inc ++ ++object
    dec –object

    예제 코드

    data class Price(private var value: Double) {
        operator fun inc(): Price {
            value++
            return this
        }
    
        operator fun dec(): Price {
            value--
            return this
        }
    }
    
    fun main() {
        var p1 = Price(5.0)
    
        println("Original p1: $p1")
    
        p1++
        println("After incrementing: $p1")
    
        p1--
        println("After decrementing: $p1")
    }
    

    참고 자료



    728x90
Designed by Tistory.