티스토리 뷰

이번 글에서는 코틀린 확장함수를 언제 사용하면 좋을지에 대해 알아봤다.

 

nextstep 미션을 수행하면서 다음과 같은 요구사항을 구현해야했다.

문자열(+, -, x, ÷)이 주어졌을 때, enum 으로 바꾸기

입력) +
결과) Operator.PLUS 

 

 

먼저 "Operator"라는 이름으로 enum class를 선언해줬다.

enum class Operator(val symbol: String) {
    PLUS("+"),
    MINUS("-"),
    MULTIPLY("x"),
    DIVIDE("÷");
}

 

 

코틀린을 공부하면서 확장함수 개념에 대해 학습했고, 이번 기회에 사용해봤다.

다음은 문자열을 Operator로 변경해주는 로직이다. 

fun String.findOperator(): Operator {
    return Operator.values().firstOrNull { it.symbol == this }

 

 

이로써 다음과 같은 방법으로 "+" 문자열을 Operator.PLUS 로 변환할 수 있다.

"+".findOperator()

 

 

리뷰어님으로부터 확장함수를 사용한 이유에 대해 커멘트를 받았다.

확장함수를 사용하지 않는 보통의 상황이라면, findOperator()를 Operator enum class 내부에 정적인 함수로 선언했을 것이다.

흠... 궁금증이 생겼다. 🤔

일반적으로 어떤 상황에서 확장함수를 사용할까?

스택오버플로우에서 비슷한 질문을 찾아 내용을 정리해봤다.


 

 

1. 기존 API를 개선, 확장 또는 변경하려는 경우

확장 함수는 기존 클래스에 새로운 기능을 추가하는 관용적인 방법이다.

참고: jackson-kotlin-module

// 기존 API인 ObjectMapper를 확장
inline fun <reified T> ObjectMapper.readValue(src: ByteArray): T = readValue(src, jacksonTypeRef<T>())

 

 

2. 기존 메서드를 nullable에서 호출 가능하도록 확장하고 싶을 때

참고: kotlin docs

fun Any?.toString(): String {
    if (this == null) return "null"
    // After the null check, 'this' is autocast to a non-nullable type, so the toString() below
    // resolves to the member function of the Any class
    return toString()
}

 

 

3. 인터페이스에 inline default 함수를 추가하고 싶을 때 (인라인 함수는 final 함수여야 하므로, 확장함수를 사용해야 한다)

참고: injekt

interface InjektRegistry {
	fun <T: Any> hasFactory(forType: TypeReference<T>): Boolean
}

inline fun <reified T: Any> InjektRegistry.hasFactory(): Boolean {
    return hasFactory(fullType<T>())
}

 

 

참고

https://stackoverflow.com/questions/35317940/when-should-one-prefer-kotlin-extension-functions

댓글