더북(TheBook)

이제 타입을 섞어 사용하면 컴파일러가 경고한다. 이는 여러분이 val weight: Weightval price: Price라고 타입을 지정하면 코틀린이 타입을 추론하는 과정에서 여러분이 예상한 타입과 컴파일러가 추론한 타입이 다를 경우 이를 알려준다는 뜻이다.

하지만 이보다 더 잘 할 수 있다. 우선, PriceWeight에 검증을 추가한다. 클래스 안에서 항등원으로 0 값을 사용할 때를 제외하면 두 타입 모두 0을 값으로 생성할 수는 없다. 팩터리 함수와 비공개 생성자를 사용하면 이런 동작을 구현할 수 있다. 다음은 Price의 경우다.

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)
        operator fun invoke(value: Double) =
            if (value > 0)
                Price(value)
            else
                throw IllegalArgumentException("Price must be positive or null")
    }
}
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.