
이 코드는 Kotlin에서 고차 함수와 함수 참조(Function Reference)를 사용하는 방법을 보여줍니다. display, greet, circleArea, cubic, root, compute 함수가 정의되어 있으며, 이를 활용해 고차 함수의 기능을 시연하고 있습니다. 각 함수의 역할을 설명드리겠습니다.
display 함수
fun display(name: String) {
println("Hello, $name!")
}
입력받은 name을 이용해 "Hello, name!" 메시지를 출력하는 함수입니다.
greet 함수 (고차 함수)
fun greet(name: String, action: (String) -> Unit) {
action(name)
}
greet 함수는 name과 action이라는 함수를 매개변수로 받습니다.
action은 String을 입력받아 반환값이 없는 함수 형태이며, greet 함수는 action(name)을 호출하여 전달받은 함수를 실행합니다.
circleArea, cubic, root 함수 (수학 관련 함수들)
fun circleArea(radius: Double): Double = Math.PI * radius * radius
fun cubic(x: Double): Double = x * x * x
fun root(x: Double): Double = Math.sqrt(x)
circleArea: 원의 반지름 radius를 받아 원의 넓이를 계산하여 반환합니다.
cubic: 주어진 x 값을 세제곱하여 반환합니다.
root: 주어진 x 값의 제곱근을 반환합니다
compute 함수 (고차 함수)
fun compute(x: Double, f: (Double) -> Double): Double = f(x)
compute 함수는 x와 f라는 함수를 매개변수로 받아, f(x)를 계산하여 반환합니다.
f는 Double을 입력받아 Double을 반환하는 함수입니다.
main 함수
fun main() {
display(name = "Alice")
val myfunct: (String) -> Unit = ::display
myfunct("Bob")
greet(name = "Alice", ::display)
val funs = listOf(::circleArea, ::cubic, ::root)
for (f in funs) {
println(compute(x = 2.0, f))
}
}
display(name = "Alice"): display 함수를 호출하여 "Hello, Alice!"를 출력합니다.
val myfunct: (String) -> Unit = ::display:
greet(name = "Alice", ::display):
val funs = listOf(::circleArea, ::cubic, ::root):
circleArea, cubic, root 함수를 참조하여 리스트로 저장합니다.
for (f in funs) 루프를 통해 funs 리스트의 각 함수에 대해 compute(x = 2.0, f)를 호출합니다.
compute(2.0, f)는 f(2.0)의 결과를 반환하므로, 각 함수에 대해 다음과 같은 결과를 출력하게 됩니다:
프로그램을 실행하면 다음과 같은 출력이 예상됩니다:
Hello, Alice!
Hello, Bob!
Hello, Alice!
12.566370614359172 // circleArea(2.0) 결과
8.0 // cubic(2.0) 결과
1.4142135623730951 // root(2.0) 결과
이 예제는 Kotlin에서 함수 참조와 고차 함수를 활용하여 다양한 함수를 동적으로 호출하는 방법을 보여줍니다. :: 연산자를 사용해 함수의 참조를 쉽게 전달할 수 있고, 이를 통해 유연한 함수 호출이 가능합니다.


이 코드는 Kotlin에서 람다 표현식, 함수 리터럴, 고차 함수, 그리고 forEach를 사용하는 다양한 방법을 보여줍니다. 각 부분을 설명드리겠습니다.
f 람다 표현식
val f: (String) -> Unit = { name: String -> println("Hello, $name!") }
String 타입의 매개변수를 받아서, "Hello, name!" 형식으로 출력하는 람다 표현식입니다.
simple 함수 리터럴
val simple = { println("Hello, Kotlin!") }
매개변수를 받지 않고 "Hello, Kotlin!"을 출력하는 함수 리터럴입니다.
Function Literal with Receiver: 수신 객체가 없는 단순한 함수 리터럴로 볼 수 있습니다.
수학 관련 람다 함수들
val circleArea2 = { radius: Double -> Math.PI * radius * radius }
val cubic2 = { x: Double -> x * x * x }
val root2 = { x: Double -> Math.sqrt(x) }
circleArea2: 원의 넓이를 계산하는 함수로, 반지름 radius를 받아 Math.PI radius radius를 계산합니다.
cubic2: 주어진 x 값을 세제곱하여 반환합니다.
root2: 주어진 x 값의 제곱근을 반환합니다.
chooseFun 함수 (고차 함수)
fun chooseFun(choice: Int) = when (choice) {
1 -> circleArea2
2 -> cubic2
else -> ::root
}
choice 값을 기준으로 해당하는 함수를 반환합니다.
1이면 circleArea2, 2이면 cubic2, 그 외에는 root 함수를 반환합니다.
main 함수
fun main() {
display(name = "Alice")
val myfunct: (String) -> Unit = ::display
myfunct("Bob")
greet(name = "Alice", ::display)
val funs = listOf(::circleArea, ::cubic, ::root)
for (f in funs) {
println(compute(x = 2.0, f))
}
val a = chooseFun(choice = 1)(3.0)
println(a)
val lambdas = listOf(circleArea2, cubic2, root2)
for (f in lambdas) {
println(compute(x = 2.0, f))
}
val arr = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9)
arr.forEach { println(it * 2) }
}
display(name = "Alice"): display 함수가 호출되어 "Hello, Alice!"가 출력됩니다.
val myfunct: (String) -> Unit = ::display:
greet(name = "Alice", ::display):
funs 리스트와 compute 함수:
val a = chooseFun(choice = 1)(3.0):
lambdas 리스트와 compute 함수:
forEach와 람다식
val arr = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9)
arr.forEach { println(it * 2) }
arr 배열의 각 요소에 대해 it * 2 값을 출력하는 람다식을 사용하여 forEach 메서드를 호출합니다.
it은 forEach 블록 내부에서 배열의 각 요소를 나타내는 키워드입니다.
프로그램을 실행하면 예상되는 출력은 다음과 같습니다:
Hello, Alice!
Hello, Bob!
Hello, Alice!
12.566370614359172 // circleArea(2.0) 결과
8.0 // cubic(2.0) 결과
1.4142135623730951 // root(2.0) 결과
28.274333882308138 // circleArea2(3.0) 결과
12.566370614359172 // circleArea2(2.0) 결과
8.0 // cubic2(2.0) 결과
1.4142135623730951 // root2(2.0) 결과
2
4
6
8
10
12
14
16
18
이 예제는 Kotlin에서 함수 참조, 람다 표현식, 고차 함수, 그리고 forEach의 사용법을 잘 보여줍니다. :: 연산자를 통해 함수를 참조할 수 있고, when을 이용해 함수 선택기를 구현할 수도 있습니다. 이러한 기능을 통해 코드를 보다 유연하고 간결하게 작성할 수 있습니다.
람다 함수와 일반 함수의 차이점을 관점별로 비교해 보겠습니다. circleArea2, cubic2, root2는 람다 함수로 작성된 예제이고, 이와 동일한 기능을 일반 함수로도 작성할 수 있습니다. 두 가지 방식의 차이점과 장단점을 살펴보겠습니다.
람다 함수
val circleArea2 = { radius: Double -> Math.PI * radius * radius }
val cubic2 = { x: Double -> x * x * x }
val root2 = { x: Double -> Math.sqrt(x) }
람다 함수는 val이나 var로 선언한 후, { 매개변수 -> 표현식 } 형식으로 작성됩니다.
일반 함수와 달리 함수 이름을 따로 정의하지 않아도 됩니다.
코드가 간결해지는 장점이 있습니다.
일반 함수
fun circleArea(radius: Double): Double = Math.PI * radius * radius
fun cubic(x: Double): Double = x * x * x
fun root(x: Double): Double = Math.sqrt(x)
일반 함수는 fun 키워드와 함수 이름을 사용해 정의합니다.
매개변수와 반환 타입을 명확하게 지정해야 합니다.
코드가 좀 더 명시적이며, 이름을 붙여서 호출하기 쉽습니다.
람다 함수
val circleArea2 = { radius: Double -> Math.PI * radius * radius }
람다 함수의 경우, 매개변수 타입은 명시적으로 지정하지만, 반환 타입은 추론됩니다.
val circleArea2의 전체 타입을 명시적으로 적으려면 다음과 같이 작성할 수 있습니다:
val circleArea2: (Double) -> Double = { radius -> Math.PI * radius * radius }
간결한 코드를 작성할 수 있지만, 큰 규모의 코드에서는 가독성이 떨어질 수 있습니다.
일반 함수
fun circleArea(radius: Double): Double = Math.PI * radius * radius
일반 함수에서는 매개변수와 반환 타입을 명확하게 지정해야 합니다.
타입이 명시적이므로 코드 읽기가 더 쉬워질 수 있으며, 코드의 가독성을 높일 수 있습니다.
람다 함수
람다 함수는 변수에 저장하여 전달하거나, 리스트와 같은 컬렉션에 추가하여 동적으로 사용할 수 있습니다.
고차 함수의 매개변수로 쉽게 전달할 수 있습니다.
val lambdas = listOf(circleArea2, cubic2, root2)
for (f in lambdas) {
println(f(2.0))
}
일반 함수
일반 함수는 함수 이름을 통해 참조할 수 있습니다.
함수 참조(::)를 사용하여 고차 함수에 전달할 수 있습니다.
val functions = listOf(::circleArea, ::cubic, ::root)
for (f in functions) {
println(f(2.0))
}
람다 함수
람다 함수는 주로 짧고 간단한 동작을 정의할 때 유용합니다.
작은 스코프(예: 지역 변수)에서 일시적으로 사용할 함수를 정의할 때 적합합니다.
코드가 복잡해질 경우 람다 표현식은 가독성을 떨어뜨릴 수 있습니다.
일반 함수
일반 함수는 코드의 재사용성을 높일 수 있습니다.
여러 곳에서 반복적으로 호출될 때 명시적인 함수 이름이 있어서 코드 이해가 쉽습니다.
큰 스코프에서도 함수의 목적을 명확하게 드러낼 수 있어 가독성이 좋습니다.
람다 함수
람다 함수를 사용하는 고차 함수에 inline 키워드를 추가하면, 성능 최적화를 할 수 있습니다.
람다 함수를 인라인(inline) 처리하여 함수 호출 오버헤드를 줄일 수 있습니다.
일반 함수
일반 함수는 inline 키워드를 사용할 수 없습니다.
반복 호출되는 경우, 일반 함수는 함수 호출 스택이 늘어나 성능에 영향을 줄 수 있습니다.
람다 함수
람다 함수는 일반적으로 val로 선언되기 때문에 변경이 불가능(immutable)합니다.
불변성을 보장할 수 있으며, 코드의 안정성이 높아집니다.
일반 함수
일반 함수는 코드 자체는 변경할 수 없지만, 재정의(override)가 가능한 구조를 가질 수 있습니다.
인터페이스나 추상 클래스에서 일반 함수를 재정의하여 다른 동작을 구현할 수 있습니다.
간결함이 필요한 경우: 람다 함수는 간단한 표현식이나 짧은 코드 블록에서 유용합니다. 특히 일회성으로 사용하는 기능을 정의할 때 적합합니다.
가독성과 재사용성이 중요한 경우: 일반 함수는 가독성이 좋고 코드가 반복해서 사용될 때 유리합니다. 함수 이름을 통해 기능을 명확히 할 수 있으며, 큰 규모의 코드에서는 일반 함수가 더 권장됩니다.
함수 참조가 필요한 경우: 일반 함수와 람다 함수 모두 함수 참조로 사용할 수 있지만, 일반 함수는 직접 ::로 참조할 수 있어 코드가 명확해지는 장점이 있습니다.
두 방법 모두 고유한 장단점이 있으므로, 상황에 따라 적합한 방식을 선택하는 것이 중요합니다.


이 코드는 Kotlin에서 data class, List, MutableList, Map, MutableMap을 사용하는 예제입니다. Menu라는 데이터를 기반으로 여러 컬렉션에 데이터를 추가하고, 이를 순회하며 출력하는 방법을 보여줍니다. 각 코드 블록을 설명드리겠습니다.
data class Menu(val name: String, val price: Int)
Menu는 name과 price라는 두 개의 속성을 가진 data class입니다.
data class는 자동으로 toString, equals, hashCode 등을 제공하므로, 데이터를 다루기 편리합니다.
1. 불변 리스트 생성 및 순회
val menus = listOf(
Menu(name = "짜장면", price = 8000),
Menu(name = "짬뽕", price = 9000),
Menu(name = "군만두", price = 8000),
Menu(name = "물만두", price = 7000)
)
for (m in menus) {
println(m)
}
listOf를 사용하여 불변 리스트 menus를 생성합니다.
각 메뉴는 Menu 객체로 초기화됩니다.
for 루프를 통해 menus 리스트를 순회하며 각 메뉴 항목을 출력합니다.
2. Iterator를 이용한 순회
val iterator = menus.iterator()
while (iterator.hasNext()) {
println(iterator.next())
}
menus.iterator()를 사용하여 Iterator 객체를 생성하고, while 루프를 통해 순회합니다.
iterator.next()를 통해 각 요소를 하나씩 출력합니다.
val board = mutableListOf<Menu>()
board.add(Menu(name = "삼계탕", price = 7500))
board.add(Menu(name = "김치찌개", price = 6000))
board.add(Menu(name = "규동", price = 9000))
for (m in board) {
println(m)
}
mutableListOf를 사용하여 가변 리스트 board를 생성합니다.
board.add(...)를 통해 메뉴 항목을 추가합니다.
for 루프를 통해 board 리스트를 순회하며 각 항목을 출력합니다.
val board2 = mutableMapOf<String, Menu>()
board2.put("1", Menu(name = "짜장면", price = 8000))
board2.put("2", Menu(name = "짬뽕", price = 9000))
board2.put("3", Menu(name = "군만두", price = 8000))
board2.put("4", Menu(name = "물만두", price = 7000))
println(board2["1"])
for (key in board2.keys) {
println(board2[key])
}
val map = mapOf(
"1" to listOf(Menu(name = "짜장면", price = 8000), Menu(name = "짬뽕", price = 9000)),
"2" to listOf(Menu(name = "군만두", price = 8000), Menu(name = "물만두", price = 7000))
)
1. Menu 데이터 클래스: name과 price 속성을 가진 메뉴를 정의합니다.
2. 불변 리스트 menus: listOf를 사용하여 메뉴 목록을 생성하고 순회합니다.
3. Iterator 사용: menus 리스트의 Iterator를 생성하여 각 요소를 출력합니다.
4. 가변 리스트 board: mutableListOf를 사용하여 메뉴 항목을 추가하고, 이를 출력합니다.
5. 가변 맵 board2: mutableMapOf를 사용하여 키-값 형태의 메뉴 맵을 생성하고, 특정 키와 모든 키에 해당하는 메뉴를 출력합니다.
6. 중첩 리스트를 가진 맵 map: mapOf를 사용하여 키에 여러 개의 메뉴를 담은 리스트를 저장합니다.
이 코드는 Kotlin의 다양한 컬렉션 타입(List, MutableList, Map, MutableMap)을 사용하여 데이터를 관리하고 순회하는 방법을 보여줍니다.