Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 스프링부트
- Collections
- pom.xml
- list
- Arrays
- GOF
- thymeleaf
- Spring Boot
- HashMap
- @Scheduled
- 프로그래머스
- 스프링 메일
- mybatis
- 프로젝트 구조
- 코딩테스트
- 스프링
- vuejs #vue #js #프론트엔드 #nodejs #클라이언트사이드 #템플릿엔진
- 스프링 스케줄러
- Dependency
- spring scheduler
- C++
- 의존성관리
- springboot
- pair
- maven
- codility
- java
- Spring Mail
- Spring
- 스프링 부트
Archives
- Today
- Total
Rooted In Develop
Kotlin - 고차 함수 본문
고차 함수 : 다른 함수를 인자로 받거나 함수를 반환하는 함수
함수 타입
val sum: (Int, Int) -> Int = ( x, y -> x + y }
val action: () -> Unit = { println(1) }
문법 : 파라미터 타입 -> 반환 타입
인자로 받은 함수 호출
fun twoAndThree(operation: (Int, Int) -> Int) {
val result = operation(2, 3)
println("result = $result")
}
>>> twoAndThree { a, b -> a + b }
result = 5
>>> twoAndThree { a, b -> a * b }
result = 6
자바에서 코틀린 함수 타입 사용
// Kotlin
fun processTheAnswer(f: (Int) -> Int) {
println(f(42))
}
// Java
>>> processTheAnswer(number -> number + 1);
43
디폴트 값을 지정한 함수 타입 파라미터나 널이 될 수 있는 함수 타입 파라미터
fun <T> Collection<T>.joinToString(
separator: String = ", ",
prefix: String = "",
postfix: String = "",
transform: (T) -> String = { it.toString() }
): String {
val result = StringBuilder(prefix)
for ((index, element) in this.withIndex()) {
if (index > 0) result.append(separator)
result.append(element)
}
result.append(postfix)
return result.toString()
}
>>> val letters = listOf("Alpha", "Beta")
>>> println(letters.joinToString())
Alpha, Beta
>>> println(letters.joinToString { it.toLowerCase() }
alpha, beta
>>> println(letters.joinToString(separator = "! ", postfix = "! ", transform = { it.toUpperCase() }))
ALPHA! BETA!
함수에서 함수를 반환
enum class Delivery { STANDARD, EXPEDITED }
class Order(val itemCount: Int)
fun getShippingCostCalculator(delivery: Delivery): (Order) -> Double {
if (delivery == Delivery.EXPEDITED) {
return { order -> 6 + 2.1 * order.itemCount }
}
return { order -> 1.2 * order.itemCount }
}
>>> val calculator = getShippingCostCalculator(Delivery.EXPEDITED)
>>> println(calculator(Order(3)))
12.3
람다를 활용한 중복 제거
data class SiteVisit(val path: String, val duration: Double, val os: OS)
eunm class OS { WINDOWS, LINUX, MAC, IOS, ANDROID }
val log = listOf(
SiteVisit("/", 34.0, OS.WINDOWS),
SiteVisit("/", 22.0, OS.MAC),
SiteVisit("/login", 12.0, OS.WINDOWS),
SiteVisit("/signup", 8.0, OS.IOS),
SiteVisit("/", 16.3, OS.ANDROID)
)
val averageWindowsDuration = log.filter { it.os == OS.WINDOWS }
.map(SiteVisit::duration)
.average()
>>> println(averageWindowsDuration)
23.0
// 일반 함수
fun List<SiteVisit>.averageDurationFor(os: OS) = filter { it.os == os }.map(SiteVisit:duration).average()
// 고차 함수
fun List<SiteVisit>.averageDurationFor(predicate: (SiteVisit) -> Boolean) = filter(predicate).map(SiteVisit::duration).average()
>>> println(log.averageDurationFor { it.os in setOf(OS.ANDROID, OS.IOS) })
12.15
>>> println(log.averageDurationFor { it.os == OS.IOS && it.path == "/signup" })
8.0
인라인 함수
- 함수를 호출하는 바이트코드 대신에 함수 본문을 번역한 바이트코드로 컴파일함
inline fun <T> synchronized(lock: Lock, action: () -> T) : T {
lock.lock()
try {
return action()
}
finally {
lock.unlock()
}
}
fun foo(l: Lock) {
println("Before Sync")
synchronized(l) {
println("Action")
}
println("After Sync")
}
// 컴파일
fun __foo__(l: Lock) {
println("Before Sync")
l.lock()
try {
println("Action")
} finally {
l.unlock()
}
println("After Sync")
}
filter, map : 인라인 함수
람다를 인자로 받는 함수를 인라이닝할 때 이익이 많다.
fun readFirstLineFromFile(path: String): String {
BufferedReader(FileReader(path)).use { br ->
return br.readLine() // non-local return
}
}
람다 안의 return
data class Person(val name: String, val age: Int)
val people = listOf(Person("Alice", 29), Person("Bob", 31))
fun lookForAlice(people: List<Person>) {
for (person in people) {
if (person.name == "Alice") {
println("Found")
return
}
}
println("Not Found")
}
fun lookForAlice(people: List<Person>) {
people.forEach {
if (it.name == "Alice") {
println("Found")
return // non-local return
}
}
println("Not Found")
}
non-local return문 : 더 바깥에 있는 다른 블록을 반환하게 하는 return문
람다로부터 반환: 레이블을 사용한 return
fun lookForAlice(people: List<Person>) {
people.forEach label@{ // 레이블 추가
if (it.name == "Alice") return@label // 앞에서 정의한 레이블 참조
}
println("Alice might be somewhere") // 항상 출력
}
fun lookForAlice(people: List<Person>) {
people.forEach {
if (it.name == "Alice") return@forEach
}
println("Alice might be somewhere") // 항상 출력
}
무명 함수: 기본적으로 로컬 return
fun lookForAlice(people: List<Person>) {
people.forEach(fun (person) {
if (it.name == "Alice") return
println("${person.name} is not Alice")
})
}
people.filter(fun (person): Boolean {
return person.age < 30
})
people.filter(fun (person) = person.age < 30)
- 무명 함수 본문의 return은 무명 함수를 반환시키고, 함수 밖의 다른 함수를 반환시키지 못한다.
'Back End > Kotlin' 카테고리의 다른 글
Kotlin - annotation, reflection (2) | 2023.06.17 |
---|---|
Kotlin - 제네릭스 (0) | 2023.06.10 |
Kotlin - 연산자 오버로딩 (0) | 2023.05.27 |
Kotlin - 타입 시스템 (0) | 2023.05.06 |
Kotlin - 클래스, 객체, 인터페이스 (0) | 2023.05.01 |
Comments