[Kotlin] 고차 함수, 람다 함수, 확장 함수 그리고 속성
고차 함수(Higher-Order Functions), 람다 함수(Lambda Functions), 확장 함수(Extension Functions) 그리고 속성(Properties)에 대해 알아봅니다.
Apr 19, 2024
![[Kotlin] 고차 함수, 람다 함수, 확장 함수 그리고 속성](https://image.inblog.dev?url=https%3A%2F%2Finblog.ai%2Fapi%2Fog%3Ftitle%3D%255BKotlin%255D%2520%25EA%25B3%25A0%25EC%25B0%25A8%2520%25ED%2595%25A8%25EC%2588%2598%252C%2520%25EB%259E%258C%25EB%258B%25A4%2520%25ED%2595%25A8%25EC%2588%2598%252C%2520%25ED%2599%2595%25EC%259E%25A5%2520%25ED%2595%25A8%25EC%2588%2598%2520%25EA%25B7%25B8%25EB%25A6%25AC%25EA%25B3%25A0%2520%25EC%2586%258D%25EC%2584%25B1%26logoUrl%3Dhttps%253A%252F%252Finblog.ai%252Finblog_logo.png%26blogTitle%3Dcode-with-me&w=2048&q=75)
고차 함수 (Higher-Order Functions)🔹 예제 1: 함수를 변수에 담기🔹 예제 2: 함수를 다른 함수의 인자로 넘기기🔹 예제 3: 함수를 리턴값으로 주기람다 함수 (Lambda Functions)확장 함수 (Extension Functions)확장 속성 (Extension Properties)정리
고차 함수 (Higher-Order Functions)
고차 함수는 함수를 매개변수로 받거나 함수를 반환하는 함수입니다. 코틀린에서는 함수가 일급 객체이기 때문에 이런 기능이 가능합니다. 일급 객체는 변수에 담을 수 있고, 함수의 인자로 넘길 수 있으며, 함수의 반환값으로 사용할 수 있는 조건을 만족한다는 뜻입니다.
// 1. 함수를 변수에 담기
val greeting = { println("Hello") }
greeting() // 실행됨
// 2. 함수를 인자로 전달하기
fun runOperation(operation: () -> Unit) {
operation()
}
runOperation(greeting)
// 3. 함수를 반환값으로 사용하기
fun getGreeting(): () -> Unit {
return { println("Hi from returned function") }
}
val greet = getGreeting()
greet()
🔹 예제 1: 함수를 변수에 담기
greeting
이라는 변수에 람다 함수(이름 없는 함수)를 할당합니다.
- 이 람다 함수를
greeting
이라는 변수에 저장한 것입니다.
- 그래서 변수 이름 뒤에 ()를 붙이면 그 함수를 실행할 수 있습니다.
👉 즉,
println("Hello")
를 출력하는 함수를 변수에 담아 놓고 나중에 실행한 거예요.🔹 예제 2: 함수를 다른 함수의 인자로 넘기기
runOperation
함수는 다른 함수를 매개변수로 받는 함수예요.
operation: () -> Unit
는 "매개변수operation
은 입력 없고 출력도 없는 함수 타입이야"라는 뜻이에요.
operation()
→ 받은 함수를 실행하는 거예요.
runOperation(greeting)
→ 아까 만든greeting
함수를 넘겨서 실행한 거예요.
👉 함수도 숫자처럼 다른 함수에 전달할 수 있다는 걸 보여줘요.
🔹 예제 3: 함수를 리턴값으로 주기
getGreeting()
은 함수를 반환하는 함수예요.
() -> Unit
은 "입력 없고 출력도 없는 함수"라는 뜻이에요.
getGreeting()
을 호출하면{ println("Hi from returned function") }
람다를 돌려줘요.
- 그걸
greet
라는 변수에 담고,greet()
로 실행한 거예요.
👉 이건 함수가 반환값이 될 수 있다는 걸 보여줘요.
// 고차 함수를 활용한 데이터 필터링 예시
fun <T> Collection<T>.customFilter(predicate: (T) -> Boolean): List<T> {
val result = mutableListOf<T>()
for (item in this) {
if (predicate(item)) {
result.add(item)
}
}
return result
}
fun main() {
val fruits = listOf("Apple", "Banana", "Cherry", "Dragonfruit", "Elderberry")
// 5글자보다 긴 과일 찾기
val longFruits = fruits.customFilter { it.length > 5 }
println("Long fruits: $longFruits") // 출력: [Banana, Cherry, Dragonfruit, Elderberry]
// 'e'를 포함하는 과일 찾기
val fruitsWithE = fruits.customFilter { it.contains('e') }
println("Fruits with 'e': $fruitsWithE") // 출력: [Apple, Cherry, Elderberry]
}
람다 함수 (Lambda Functions)
람다 함수는 이름 없이 즉시 사용하는 함수식으로 람다식은 중괄호 {} 안에 정의하고 매개변수가 있으면 → 기호로 구분해요. Kotlin으로 코드를 작성하다보면 람다 함수를 자주 사용하게 되는데 다음과 같이 작성합니다.
data class Student(val name: String, val age: Int, val grade: Double)
fun main() {
val students = listOf(
Student("Alice", 20, 3.8),
Student("Bob", 22, 3.2),
Student("Charlie", 19, 4.0),
Student("Diana", 21, 3.5)
)
// 람다를 활용한 데이터 처리 파이프라인
val honorStudents = students
.filter { it.grade >= 3.5 }
.sortedByDescending { it.grade }
.map { "${it.name} (GPA: ${it.grade})" }
println("Honor Students:")
honorStudents.forEach { println("- $it") }
// 출력:
// Honor Students:
// - Charlie (GPA: 4.0)
// - Alice (GPA: 3.8)
// - Diana (GPA: 3.5)
}
확장 함수 (Extension Functions)
확장 함수는 기존 클래스에 새로운 함수를 추가하는 기능입니다. 라이브러리나 프레임워크의 코드를 수정하지 않고도 새로운 기능을 추가할 수 있습니다.
마찬가지로 데이터를 받아서 UI에 표시할 때 날짜 처리를 해야하는 경우가 생기는데 다음과 같은 예시로 확장 함수를 이용합니다.
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit
// LocalDate 클래스에 대한 확장 함수들
fun LocalDate.formatKorean(): String {
return this.format(DateTimeFormatter.ofPattern("yyyy년 MM월 dd일"))
}
fun LocalDate.daysUntil(other: LocalDate): Long {
return ChronoUnit.DAYS.between(this, other)
}
fun LocalDate.isWeekend(): Boolean {
val dayOfWeek = this.dayOfWeek.value
return dayOfWeek == 6 || dayOfWeek == 7 // 토요일(6) 또는 일요일(7)
}
fun main() {
val today = LocalDate.now()
val futureDate = today.plusDays(10)
println("오늘: ${today.formatKorean()}")
println("10일 후: ${futureDate.formatKorean()}")
println("남은 일수: ${today.daysUntil(futureDate)}일")
println("오늘은 주말인가요? ${today.isWeekend()}")
}
확장 속성 (Extension Properties)
코틀린에서 확장 속성은 확장 함수와 마찬가지로 클래스에 확장 속성도 추가할 수 있습니다.
// String 클래스에 확장 속성 추가
val String.wordCount: Int
get() = this.split(Regex("\\s+")).filter { it.isNotEmpty() }.size
val String.vowelCount: Int
get() = this.count { it.lowercase() in "aeiou" }
val String.isEmail: Boolean
get() = matches(Regex("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$"))
fun main() {
val text = "The quick brown fox jumps over the lazy dog"
println("단어 수: ${text.wordCount}") // 출력: 9
println("모음 수: ${text.vowelCount}") // 출력: 11
val email1 = "user@example.com"
val email2 = "invalid-email"
println("$email1 은 유효한 이메일인가? ${email1.isEmail}") // 출력: true
println("$email2 은 유효한 이메일인가? ${email2.isEmail}") // 출력: false
}
정리
코틀린의 고차 함수, 람다, 확장 함수와 속성은 코드를 더 간결하고 표현력 있게 만들어 줍니다. 다음과 같은 이점이 있습니다.
- 코드 재사용성 향상
- 함수형 프로그래밍 지원
- API 설계의 유연성 (다양한 콜백과 리스너를 더 간결하게 구현)
Share article