본문 바로가기

Android

Extension fun, 코틀린 기초 문법 (2) - Koans 풀이

반응형

오늘은 Kotlin 공식 홈페이지 기초 문법에 대한 문제 풀이를 적어보려 합니다. Extension Functions에 대한 내용인데, 공식에서 읽어보라고 한 문서를 읽어도 이해가 잘 안가서리...

 

Kotlin Playground: Edit, Run, Share Kotlin Code Online

 

play.kotlinlang.org

문제: Extension functions

Read about extension functions. Then implement extension functions Int.r()and Pair.r() and make them convert Int and Pair to RationalNumber.

fun Int.r(): RationalNumber = TODO()
fun Pair<Int, Int>.r(): RationalNumber = TODO()

data class RationalNumber(val numerator: Int, val denominator: Int)

위 코드가 테스트 케이스에 대해 작동하게 만들기만 하면 됩니다. 두 함수 모두 return 값이 RationalNumber이므로 일단 아래와 같이 러프한 값을 넣어봅니다.

fun Int.r(): RationalNumber = RationalNumber(1, 1)
fun Pair<Int, Int>.r(): RationalNumber = RationalNumber(1, 1)

data class RationalNumber(val numerator: Int, val denominator: Int)

이러면 아래와 같은 에러가 뜹니다.

Fail: testPairExtension: Rational number creation error: expected:<RationalNumber(numerator=2, denominator=3)> but was:<RationalNumber(numerator=1, denominator=1)>
Fail: testIntExtension: Rational number creation error: expected:<RationalNumber(numerator=4, denominator=1)> but was:<RationalNumber(numerator=1, denominator=1)>

아래와 같이 값을 고치면 해결!!

fun Int.r(): RationalNumber = RationalNumber(4, 1)
fun Pair<Int, Int>.r(): RationalNumber = RationalNumber(2, 3)

data class RationalNumber(val numerator: Int, val denominator: Int)

Passed: testPairExtension
Passed: testIntExtension

물론 이렇게 값만 러프하게 넣어서 해결해도 되지만;;; 실력 향상을 위해 모든 다른 케이스에 대해서도 동작하도록 만드는 게 중요하겠죠? 상수에서 적절한 변수로 바꿔주면 되겠죠. 그런데 어떤 변수를 넣어야 할지 모르겠습니다. 문제에서 제시한 extension functions 문서를 읽어봅시다. 해당 문서를 첫 문단만 번역해봤습니다.

 

Extensions - Kotlin Programming Language

 

kotlinlang.org

코틀린에서는 클래스를 상속하거나, 데코레이터 같은 디자인 패턴을 사용하지 않고 클래스를 확장할 수 있습니다. extensions 특별한 선언을 통해 이루어집니다. 이 방법을 통해, 코드를 수정할 수 없는 써드파티 라이브러리 클래스에 새로운 함수를 작성할 수 있습니다. 이런 함수는 원래 메서드와 같은 방법으로 호출할 수 있습니다. 이런 메커니즘은 extension functions라 불립니다. 또한, 이미 정의된 클래스에 새로운 속성을 추가하는 extension properties가 있습니다.

아하! 답이 나왔습니다. 우리가 정의할 Int.r()Pair.r()은 클래스 메서드로 작동합니다. 그러면 Int와 Pair의 선언을 보면 우리에게 필요한 변수에 대해서도 알 수 있겠죠?

 

Int - Kotlin Programming Language

 

kotlinlang.org

Int에 대한 문서를 보면, 파라미터를 사용하지 않는 메서드는 하나같이 해당 작업을 this value에 대해 수행한다고 합니다. 우리 코드를 한 번 고쳐볼까요?

fun Int.r(): RationalNumber = RationalNumber(this, 1)
fun Pair<Int, Int>.r(): RationalNumber = RationalNumber(2, 3)

data class RationalNumber(val numerator: Int, val denominator: Int)

Passed: testPairExtension
Passed: testIntExtension

아까와 마찬가지로 테스트를 패스합니다. 하지만 테스트하려는 값이 바뀌어도 Int.r()은 계속계속 테스트를 통과하겠죠? 다음으로 Pair에 대한 문서를 찾아봅시다.

 

Pair - Kotlin Programming Language

 

kotlinlang.org

Pair는 first와 second, 두 가지 속성을 가지고 있습니다. 그렇다면 메서드에서 사용할 수 있는 값의 이름도 당연히 first와 second겠죠?

fun Int.r(): RationalNumber = RationalNumber(this, 1)
fun Pair<Int, Int>.r(): RationalNumber = RationalNumber(first, second)

data class RationalNumber(val numerator: Int, val denominator: Int)

Passed: testPairExtension
Passed: testIntExtension

이로써 테스트를 완벽하게 통과했습니다. Extension Functions에 대한 개념은 없어도 눈치코치로 알아맞힐 수 있었는데, 파라미터 값을 몰랐던 건 지금 보니 그냥 기초 지식이 부족했던 것 같네요... 더욱 정진해야겠습니다...

반응형