코틀린은 클래스 상속이나 데코레이터 패턴 등을 사용하지 않고도 클래스나 인터페이스를 확장하는 기능을 제공합니다. 이를 확장 함수라 이릅니다. 사용법이 간단해서 여기 저기 써먹기 좋습니다.
기본적인 사용법은 다음과 같습니다.
fun Int.multiplier(parameter: Int) : Int {
return this * parameter
}
정수값에 multiplier(n) 메서드를 호출하면 해당 정수값 x n 해주는 함수입니다.
fun main() {
12.multiplier(3)
}
// Console
System.out: 36
제가 직접 사용중인 예제는 아래와 같습니다.
private fun ArrayList<String>?.addIfExists(text: String) {
this.let {
it?.add(text)
}
}
ArrayList 가 Nullable 인 경우, Null 이 아닐 때에만 특정 값을 넣고 싶을 때 사용합니다.
이 경우가 몇 번 없으면 굳이 확장 함수를 쓰지 않겠지만, 여러 번 수행해야 한다면 함수를 만드는 게 낫습니다. 일반 함수를 생성해서 사용해도 무관하지만, 함수를 호출할 때마다 파라미터로 ArrayList 를 넘겨줘야 하는 번거로움이 있습니다. 확장 함수로 사용하면, 해당 객체에서 바로 호출하면 되기 때문에 보다 간편합니다.
다음과 같이 사용합니다.
fine > 255 -> {
reasonList.addIfExists("미세먼지 나쁨 (-25)")
point -= 25
}
해당 함수의 경우, 접근제어자를 private 로 선언해두었기 때문에, 해당 경로 외부에서는 사용할 수 없습니다.
fun CoroutineScope.io(codeBlock: suspend CoroutineScope.() -> Unit) =
CoroutineScope(IO).launch {
codeBlock()
}
위와 같이 파라미터로 함수를 넣어 줄 수도 있습니다. 해당 확장 함수는 IO Scope 에서 코루틴을 실행하는 함수입니다. 일반적인 코루틴 생성은 다음과 같습니다.
CoroutineScope(Dispatchers.IO).launch {
// do Something
}
긴 코드는 아니지만, 코루틴 호출이 잦으면 이 과정마저 번거롭기도 합니다. 확장 함수로 구현해두면 쉽고 편하게 사용할 수 있습니다. 실 사용은 다음과 같습니다.
CoroutineScopes.io {
repository.fetchDogList().collect { dogs ->
if (dogs.isNotEmpty()) {
_dogsFlow.emit(
DogsStateHandler.Success(dogs)
)
} else {
_dogsFlow.emit(
DogsStateHandler.Failure("List is empty.")
)
}
}
}
사실 확장 함수는 어느 정도 알고는 있었습니다. 제가 몰랐을만한 별도의 용례가 있으면 학습하려고 했으나, 그다지 거창한 개념은 아니라 딱히 사례가 없었습니다.
'Kotlin' 카테고리의 다른 글
Generics 와 Reified 키워드 (0) | 2023.04.21 |
---|---|
by 를 사용한 Kotlin 의 Delegation Pattern (0) | 2022.11.17 |
ChannelFlow, CallbackFlow 제대로 알기 (0) | 2022.11.03 |
Channel 제대로 알기 (0) | 2022.11.02 |
StateFlow, SharedFlow 제대로 알기 (0) | 2022.11.01 |