1. 확장 함수란?
코틀린의 확장 함수(extension function)는 기존 클래스에 멤버 함수를 추가하는 것처럼 사용할 수 있도록 해주는 기능입니다. 확장 함수를 사용하면 클래스를 수정하거나 상속받을 필요 없이 새로운 메서드를 정의하여, 해당 클래스의 인스턴스에서 바로 호출할 수 있습니다.
1-1 확장 함수의 정의 방법
확장함수를 정의하기 위해선 함수 이름 앞에 수신 객체 타입을 붙입니다. 수신 객체 타입은 확장 대상이 되는 클래스로 기본적인 형태는 아래와 같습니다.
fun, 수신타입.확장함수() { ...}
1-2 기존 클래스를 확장해 기능을 추가하기
예를 들어 문자열에 ''붙여 반환해주는 새로운 기능을 추가한다고 생각해봅시다.
fun main() {
val result = "안녕".singleQuote()
println(result) // '안녕' 출력
}
fun String.singleQuote(): String {
return "'$this'"
}
다음과 같이 singleQuote 확장함수를 정의하면 마치 String클래스의 멤버 함수인 것처럼 호출할 수 있습니다.
- singleQuote 함수는 String 클래스의 멤버 함수처럼 보이지만, 실제로 클래스 내부에는 추가되지 않습니다.
- 다른 패키지에서 이 확장 함수를 사용하려면 해당 함수를 import해야 합니다.
1-3 특정 작업을 직관적으로 표현하기
확장 함수는 클래스와 관련된 특정 작업을 더욱 직관적으로 표현할 수 있습니다.
예를 들어, 리스트에서 짝수만 필터링하는 기능을 추가하려고 할 때, 확장 함수를 사용하면 다음과 같이 정의할 수 있습니다.
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
val evens = numbers.filterEven()
println(evens)
}
fun List<Int>.filterEven(): List<Int> {
return this.filter { it % 2 == 0 }
}
- filterEven 함수는 List 클래스의 메서드처럼 동작합니다.
- List 객체와 관련된 작업을 확장 함수로 정의하면, 작업 대상과 함수가 명확히 연결됩니다.
- 기존 클래스에 영향을 주지 않고도 기능을 확장할 수 있어 유지보수가 쉽습니다.
1-4 확장성과 안정성
확장 함수는 컴파일 타임에 결정되므로 클래스의 실제 코드를 변경하지 않고도 새로운 기능을 추가할 수 있습니다. 이로 인해 다음과 같은 장점이 있습니다.
- 안전성: 클래스 정의 자체에는 영향을 주지 않으므로 기존 코드와 충돌하지 않습니다.
- 확장성: 특정 작업을 수행하는 함수를 쉽게 추가하고 재사용할 수 있습니다.
기존 String이나 List와 같은 클래스에 원하는 작업을 추가하면서도, 코틀린 표준 라이브러리와 충돌하지 않고 사용할 수 있습니다.
2. 이름 붙은 인자와 디폴트 인자
코틀린은 함수를 호출하면서 인자의 이름을 명시적으로 작성해서 값을 전달할 수 있습니다.
fun main() {
println(color(1, 2, 3)) //(1,2,3) 출력
println(color(red = 1, green = 2, blue = 3)) // (1, 2, 3) 출력
}
fun color(red: Int, green: Int, blue: Int) =
"($red, $green, $blue)"
이름 붙은 인자를 활용함으로써 각 인자의 의미를 명확히 전달할 수 있어 가독성을 높이고, 코드를 읽는 사람이 쉽게 이해할 수 있습니다.
2-1 순서에 의존하지 않는다
이름이 붙은 인자를 사용하면 인자의 순서와 상관없이 값을 전달할 수 있습니다.
fun main() {
println(color(1, 2, 3)) //(1,2,3) 출력
println(color(green = 2, red = 1, blue = 3)) // (1, 2, 3) 출력
}
fun color(red: Int, green: Int, blue: Int) =
"($red, $green, $blue)"
이름이 붙은 인자를 사용해 함수를 호출한 println(color(green = 2, red = 1, blue = 3))의 경우 함수에 정의된 순서에 따라 1,2,3 이 출력되는 것을 볼 수 있습니다.
- 인자의 순서가 바뀌어도 함수 호출이 동작하므로, 순서를 기억할 필요가 없다.
- 특히, 많은 매개변수를 가진 함수에서 일부 인자만 전달할 때 유용하다.
이 때 주의할 점은 이름이 붙은 인자와 일반 인자(위치 기반)를 섞어서 사용할 경우 인자 순서를 변경하고 나면 인자 목록의 나머지 부분에서도 이름 붙은 인자를 사용해야 합니다.
=> (컴파일러가 이름이 생략된 인자들의 위치를 알아내지 못할 수 있기 때문)
2-2 디폴트 매개변수와 함께 사용
디폴트 값을 가진 매개변수와 함께 사용하면 전달할 필요가 없는 값을 생략하면서도 명확하게 호출이 가능합니다.
fun main() {
println(color(139)) // (139,0,0) 출력
println(color(blue = 139)) // (0,0,139) 출력
println(color(red = 1, blue = 2)) //(1,0,2) 출력
}
fun color(
red: Int = 0,
green: Int = 0,
blue: Int = 0
) = "($red, $green, $blue)"
함수 호출 시 값을 지정하지 않은 인자는 자동으로 디폴트 값으로 지정됩니다.
- 선택적으로 필요한 값만 전달할 수 있어 코드가 간결해진다.
- 인자의 역할을 명시하므로, 어떤 값이 생략되었는지 쉽게 알 수 있다.
3. 총정리
확장함수
- 기존 클래스에 새로운 기능을 추가
- 클래스 수정이나 상속 업싱 구현이 가능
- 작업 대상을 명확히 연결해 코드 직관성과 가독성을 향상
이름 붙은 인자
- 함수 호출 시 인자의 이름을 명시해 값을 전달한다.
- 인자의 순서에 의존하지 않아 유연함
- 많은 매개변수 중 필요한 것만 명확히 지정이 가능
디폴트 매개변수
- 매개변수에 기본값을 지정해 호출을 단순화
- 이름 붙은 인자와 함께 사용 시 선택적 호출이 가능
'Kotlin 정리' 카테고리의 다른 글
[Kotlin 공부 7일차] 데이터 클래스, 구조 분해 선언 (0) | 2024.12.10 |
---|---|
[Kotlin 공부 6일차] 오버로딩, when (0) | 2024.12.06 |
[Kotlin 공부 4일차] 객체, 클래스, 생성자 (0) | 2024.12.02 |
[Kotlin 공부 3일차] 루프와 범위 (0) | 2024.11.29 |
[Kotlin 공부 2일차] 코틀린에서 함수와 조건문(if), 문자열 템플릿 다루기 (0) | 2024.11.28 |