연산자 오버로드를 할 때는 의미에 맞게 사용하라
fun Int.factorial(): Int = (1..this).product()
fun Iterable<Int>.product(): Int =
fold(1) { acc, i -> acc * i }
위와 같이 확장함수로 구현한다면 6.factorial()로 편리하게 사용할 수 있다.
operator fun Int.not() = factorial()
또한 연산자에 오버로드 한다면, !6
으로 만들어 낼 수 있다. 하지만 논리연산자 !을 의미하는 것으로, 오해의 소지가 있으므로 팩토리얼 연산에 사용해서는 안된다.
결론은, 관례로 사용되는 연산자들은 오버로딩하지 말자.
관례를 충족하는지 아닌지 확실하지 않을 때가 있다. 예를 들어 함수를 세 배한다고 한다면, 함수를 3번 반복하는 새로운 함수를 만들어 낸다고 생각할 수 있고, 함수를 3번 호출한다고 생각할 수 있다.
의미가 명확하지 않는다면, infix 함수를 활용해 확장 함수로 나타내자.
infix fun Int.timesRepeated(operation: () -> Unit) = {
repeat(this) { operation() } //this는 Int 의미
}
val tripledHello = 3 timesRepeated { print("Hello") } //infix로 이름을 가지도록
tripledHello() // HelloHelloHello 출력
DSL 을 사용할 때는 연산자 오버로딩 규칙을 무시해도 된다.
왜????.. 조사필요
잘 봤습니다. 좋은 글 감사합니다.