#17 Kotlin Koans Conventions/Operators overloading 해설

1 소개



Kotlin 공식 레퍼런스의 Kotlin Koans/Operators overloading의 해설 기사입니다.

Kotlin Koans를 통해 Kotlin을 배우는 사람들의 도움이 되길 바랍니다.

다만, 레퍼런스를 자력으로 읽는 힘을 기르고 싶은 분은,
곧이 기사를 보지 마십시오!

한 번 각자로 도전하고 나서, 눈에 띄게 된다고 생각합니다

2 plus() 함수/times() 함수



두 함수 모두 operator 한정자가 있고,
a + b a.plus(b)a * b a.times(b)
를 표현합니다.

( Operator overloading )

3 Conventions/Operators overloading 해설



Kotlin Koans Conventions/Operators overloading의 해설입니다.
수시로 본 사이트의 내용을 인용하겠습니다.

본문과 코드를 살펴보자.

Implement a kind of date arithmetic. Support adding years, weeks and days to a date. You could be able to write the code like this: date + YEAR * 2 + WEEK * 3 + DAY * 15.

At first, add an extension function 'plus()' to MyDate, taking a TimeInterval as an argument. Use an utility function MyDate.addTimeIntervals() declared in DateUtil.kt

Then, try to support adding several time intervals to a date. You may need an extra class.

Operators_overloading
import TimeInterval.*

data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int)

enum class TimeInterval { DAY, WEEK, YEAR }

operator fun MyDate.plus(timeInterval: TimeInterval): MyDate = TODO()

fun task1(today: MyDate): MyDate {
    return today + YEAR + WEEK
}

fun task2(today: MyDate): MyDate {
    TODO("Uncomment") //return today + YEAR * 2 + WEEK * 3 + DAY * 5
}

DateUtil.kt
import java.util.Calendar

fun MyDate.addTimeIntervals(timeInterval: TimeInterval,number: Int):MyDate{
    val c = Calendar.getInstance()
    c.set(year,month,dayOfMonth)
    when(timeInterval){
        TimeInterval.DAY -> c.add(Calendar.DAY_OF_MONTH,number)
        TimeInterval.WEEK -> c.add(Calendar.WEEK_OF_MONTH,number)
        TimeInterval.YEAR -> c.add(Calendar.YEAR,number)
    }
    return MyDate(c.get(Calendar.YEAR),c.get(Calendar.MONTH),c.get(Calendar.DATE))  
}
task1()를 호출하면 today + YEAR + WEEK가 정확하게 호출하에 반환되도록task2() 를 호출하면 today + YEAR * 2 + WEEK * 3 + DAY * 5 가 정확하게 호출하에 반환되도록 구현합니다.

task1()에서 생각합시다.

MyDate 형의 today가 today.plus(YEAR) 와 같이 plus() 함수를 호출합니다. 반환 값이 plus() 함수에 인수WEEK를 전달하여 참조합니다.

plus () 함수의 반환 값을 디자인하기 위해 DateUtil.ktファイルaddTimeIntervals()를 사용하도록 지시가 있기 때문에,

Operators_overloading
operator fun MyDate.plus(timeInterval: TimeInterval) = addTimeIntervals(timeInterval, 1)

처럼 디자인합니다.

(※ addTimeIntervals()는 인수로서 받은 TimeInterval형의 프로퍼티(DAY/WEEK/YEAR)에 number의 수를 더한 것을 MyDate형의 인스턴스의 프로퍼티에 대입해 반환값으로 합니다.)

다음으로 task2()에 대해 생각해 봅시다.
TODO("Uncomment")//를 삭제하면 return today + YEAR * 2 + WEEK * 3 + DAY * 5가 take2()의 반환 값입니다.
YEAR * 2YEAR.times(2)를 의미하므로 times()를 구현해야 합니다.

그러므로

Operators_overloading
operator fun TimeInterval.times(number: Int)

와 같이 times()를 설정합니다.
return today + YEAR * 2 + WEEK * 3 + DAY * 5를 생각하면,
today가 호출하는 plus()의 반환값에서는 addTimeintervals(timeInterval,1) 그대로 이용하고 싶은 곳입니다만,
YEAR * 2 (YEAR.times(2)) 는 반환 값으로 TimeInterval 형식을 반환 할 수 없으므로,
TimeInterval型とnumberをプロパティとして持つクラス를 만들어야 합니다.

그러므로

Operators_overloading
class RepeatedTimeInterval(val timeInterval: TimeInterval,val number: Int)
operator fun TimeInterval.times(number: Int) = RepeatedTimeInterval(this, number)

와 같이 times() 와 새롭게 RepeatedTimeIntervalクラス 를 구현합니다.

즉, YEAR * 2는 RepeatedTimeInterval 유형의 인스턴스가 반환됩니다.

이에 따라, today가 plus()에 건네주는 인수는 기존의 plus()(인수로서 TimeInterval型를 받는다.)에서는 받을 수 없기 때문에,

인수로서 RepeatedTimeInterval 형의 인스턴스를 받는 plus() 를 구현합니다.

Operators_overloading
operator fun MyDate.plus(timeIntervals: RepeatedTimeInterval) = addTimeIntervals(timeIntervals.timeInterval, timeIntervals.number)

완성된 전체 코드는 다음과 같습니다.

Operators_overloading
import TimeInterval.*

data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int)

enum class TimeInterval { DAY, WEEK, YEAR }

operator fun MyDate.plus(timeInterval: TimeInterval) = addTimeIntervals(timeInterval, 1)

class RepeatedTimeInterval(val timeInterval: TimeInterval, val number: Int)
operator fun TimeInterval.times(number: Int) = RepeatedTimeInterval(this, number)

operator fun MyDate.plus(timeIntervals: RepeatedTimeInterval) = addTimeIntervals(timeIntervals.timeInterval, timeIntervals.number)

fun task1(today: MyDate): MyDate {
    return today + YEAR + WEEK
}

fun task2(today: MyDate): MyDate {
    return today + YEAR * 2 + WEEK * 3 + DAY * 5
}


4 마지막으로



다음은 Kotlin Koans Conventions/Destructuring declarations의 해설을 하겠습니다

좋은 웹페이지 즐겨찾기