확장 함수 (Extension Function) 더보기
확장 함수는 [확장을 하려는 대상.함수]로 만들 수 있다고 하였습니다. 여기서 함수는 일반 함수의 형태입니다.
[Remind] 함수의 기본 형태
fun 함수명(변수): Unit { } or fun 함수명(변수): 리턴타입 { return 값 } |
여기에서 '확장을 하려는 대상'을 추가해주면 확장 함수가 됩니다. 엄밀히 말하자면 '확장 하려는 대상'에 함수를 추가해주는 것이겠죠.
fun 확장 하려는 대상.함수명(변수): Unit { } or fun 확장 하려는 대상.함수명(변수): 리턴타입 { return 값 } |
앞서 직접 만든 Car 클래스를 '확장 하려는 대상(receiver type)'으로 확장 함수를 만들어 봤습니다. 그런데 Basic Type을 이용하면 좀 더 재미있는 일을 할 수 있을 것 같습니다. Basic Type은 Int, Double, Byte와 같은 Number를 비롯에 Boolean, Array, String까지 다양합니다.
예를 들어 String의 길이를 비교하여 길이가 더 긴 String을 리턴 받는 확장 함수를 만들어 사용할 수 있습니다.
fun main(args: Array<String>) { println("Hello".getLonggerString("Hi")) } fun String.getLonggerString(x: String) : String { return if(this.length > x.length) this else x } |
Hello |
예제를 분석해보면 확장 함수를 사용할 때의 형태가 보입니다.
"Hello".getLongger("Hi") ↓ 확장을 하려는 대상.확장 함수명(확장함수 파라미터 타입) ↓ String.getLonggerString(String) |
여기서는 확장을 하려는 대상, 즉 receiver type이 String이고 확장 함수명은 getLonggerString 그리고 파라미터 타입은 String입니다.
곧이곧대로 사용하면 재미없으니 이걸 약간 변형시켜 응용해볼까요?
fun main(args: Array<String>) { println("Hello".getLonggerLength(3)) } fun String.getLonggerLength(x: Int) : Int { return if(this.length > x) this.length else x } |
5 |
이번엔 String인 Hello의 길이와 3을 비교하여 큰 수를 리턴 받습니다. 확장 함수의 리턴타입과 파라미터 타입을 변경한 것입니다. 그러면 파라미터 타입은 String으로 유지한채 두 String 중 길이가 더 긴 String의 length를 리턴 받는 확장 함수도 만들 수 있겠죠? 또 파라미터 2개를 받아서 뭔가를 할 수도 있을 것입니다. 한 번 생각해보시면 좋을 것 같습니다.
중위 표기법 (Infix notation)
1. 멤버 함수 또는 확장 함수여야 한다. 2. 하나의 파라미터를 가져야 한다. 3. infix 키워드를 사용해야 한다. |
그럼 '두 String 중 길이가 더 긴 String의 length를 리턴 받는 확장 함수'를 이참에 한 번 만들어 보겠습니다.
fun main(args: Array<String>) { println("Hello".getLonggerStringLength("Have a nice day!")) } fun String.getLonggerStringLength(x: String) : Int { return if(this.length > x.length) this.length else x.length } |
16 |
함수명이 점점 거창해지고 가독성이 떨어지고 있습니다. (^^;)
자, 이 예제는 확장 함수이며 하나의 파라미터를 가지고 있습니다. 따라서 infix만 선언해주면 중위 표기법으로 호출이 가능하게 됩니다.
fun main(args: Array<String>) { println("Hello" getLonggerStringLength "Have a nice day!") } infix fun String.getLonggerStringLength(x: String) : Int { return if(this.length > x.length) this.length else x.length } |
16 |
기존 방식과 중위 표기법으로 호출한 방식이 차이는 다음과 같습니다.
"Hello".getLonggerStringLength("Have a nice day!") "Hello" getLonggerStringLength "Have a nice day!" |
기본 형태로 보면 좀 더 간결합니다. .(dot) 대신에 공백 그리고 함수명 다음에 공백을 추가하고 파라미터의 괄호가 사라졌습니다.
receiverType.함수명(파라미터) ↓ receiverType 함수명 파라미터 |
확장 함수 vs 멤버 함수
fun main(args: Array<String>) { val car = Car() println(car.getPrice()) } class Car { fun getPrice(): Int { return 10000 } } fun Car.getPrice(): Int { return 20000 } |
10000 |
하지만 함수 이름이 같아도 멤버 함수를 overload한 확장 함수는 확장 함수가 호출이 됩니다.
fun main(args: Array<String>) { val car = Car() println(car.getPrice(0)) } class Car { fun getPrice(): Int { return 10000 } } fun Car.getPrice(price: Int): Int { return 20000 } |
20000 |
'프로그래밍 > Kotlin' 카테고리의 다른 글
코틀린 Higher-Order Functions #1 (0) | 2017.12.20 |
---|---|
코틀린(Kotlin) Control Flow #2 (0) | 2017.12.19 |
코틀린(Kotlin) Control Flow #1 (0) | 2017.12.17 |
코틀린(Kotlin) 확장(Extension) #1 (0) | 2017.12.14 |
코틀린(Kotlin) 개발환경 구축 (0) | 2017.12.13 |
코틀린(Kotlin) 함수(function) #1 (0) | 2017.12.13 |
코틀린(Kotlin) 추상클래스 & 인터페이스 (0) | 2017.12.11 |