operator overloading Kotlin


연산자 오버로딩은 키워드 역할을 하는 메소드를 구현함으로서 지원됨

1. 기본 연산
plus, minus, times, div, rem
plusAssign, minusAssign, timesAssign, divAssign, remAssign
data class Point(val x: Int, val y: Int) {
operator fun plus(other: Point): Point {
return Point(x + other.x, y + other.y)
}
}

fun a() {
val p1 = Point(10, 20)
val p2 = Point(30, 40)
println(p1 + p2)
}


operator fun Point.times(scale: Double): Point {
return Point((x * scale).toInt(), (y * scale).toInt())
}

fun a() {
val p = Point(10, 20)

println(p*1.5)
}
2. 단항연산
unaryMinus, unaryPlus, 

operator fun Point.unaryMinus(): Point {
return Point(-x, -y)
}
not, inc, dec: !, ++x, x++, --x, x--

operator fun BigDecimal.inc() = this + BigDecimal.ONE
fun a() {
var bd=BigDecimal.ZERO
println(bd++)//0
println(++bd)//2
}

3. 비교 연산
equals: == , 널의 경우도 포함해서 처리, operator가 아닌 override 를 사용
a==b -> a?.equals(b) ?: b==null

compareTo
a >= b -> a.compareTo(b) >= 0

class Person(val firstName: String, val lastName: String) : Comparable<Person> {
override fun compareTo(other: Person): Int {
return compareValuesBy(this, other, Person::lastName, Person::firstName)
}
}

fun a() {
val p1 = Person("Alice", "Smith")
val p2 = Person("Bob", "Johnson")
println(p1 < p2)
}

4. 원소접근연산
get, set
arr[index]
map[key]
x[a,b] -> x.get(a, b)

operator fun Point.get(index: Int): Int {
return when (index) {
0 -> x
1 -> y
else -> throw IndexOutOfBoundsException("Invalid coordinate $index")
}
}

fun a() {
val p1 = Point(10, 20)
println("${p1[0]}, ${p1[1]}")
}

마지막 파라미터만 = 우항에 들어가서 set이 구현됨
a[1]=
x[a,b]=c -> x.set(a,b,c)

data class Point(var x: Int, var y: Int) {
operator fun plus(other: Point): Point {
return Point(x + other.x, y + other.y)
}
}
operator fun Point.set(index: Int, value: Int) {
when (index) {
0 -> x = value
1 -> y = value
else ->
throw IndexOutOfBoundsException("Invalid coordinate $index")
}
}

fun a() {
val p1 = Point(10, 20)
p1[0] = 2
println("${p1[0]}, ${p1[1]}")
}
5. 포함여부 확인 연산
contains
a in c -> c.contains(a)

data class Rectangle(val upperLeft: Point, val lowerRight: Point) {

}

operator fun Rectangle.contains(p: Point): Boolean {
return p.x in upperLeft.x until lowerRight.x && p.y in upperLeft.y until lowerRight.y
}

fun a() {
val rect = Rectangle(Point(10, 20), Point(50, 50))
println(Point(20, 30) in rect)
println(Point(5, 5) in rect)
}


6. 범위 연산
rangeTo
start..end -> start.rangeTo(end)

operator fun <T:Comparable<T>> T.rangeTo(that: T): ClosedRange<T>
범위를 반환, 어떤 원소가 그 범위 안에 들어있는지 in을 통해 검사할 수 있음

val now = LocalDate.now()
val vacation = now..now.plusDays(10)
println(now.plusWeeks(1) in vacation)
(0..n).forEach{print(it)}

7. iterator 연산
iterator for 문에서 사용하기 위함


operator fun ClosedRange<LocalDate>.iterator(): Iterator<LocalDate> {
return object : Iterator<LocalDate> {
var current = LocalDate.now()
override fun hasNext(): Boolean {
return true
}

override fun next(): LocalDate {
return current.apply {
current = plusDays(1)
}
}
}
}

fun b() {
val newYear = LocalDate.ofYearDay(2017, 1)
val daysOff = newYear.minusDays(1)..newYear
for (dayOff in daysOff) {
println(dayOff)
}
}

8. 구조분해 연산
componentN 함수 (component1, component2,..)
val p = Point(10, 20)
val (x, y) = p
println("$x, $y")





덧글

댓글 입력 영역