JAVA

kotlin operator invoke 로 데이터 검증 하기!

lahuman 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