๊นจ์•Œ ๊ฐœ๋… ๐Ÿ“‘/Kotlin

[Kotlin] ํ•จ์ˆ˜ ํƒ€์ž…(Fuction types) ํ‘œํ˜„์‹

interfacer_han 2024. 1. 31. 10:17

#1 ์ฝ”ํ‹€๋ฆฐ์˜ ํ•จ์ˆ˜๋Š” ์ผ๊ธ‰ ๊ฐ์ฒด๋‹ค

 

์ผ๊ธ‰ ๊ฐ์ฒด - ์œ„ํ‚ค๋ฐฑ๊ณผ, ์šฐ๋ฆฌ ๋ชจ๋‘์˜ ๋ฐฑ๊ณผ์‚ฌ์ „

์œ„ํ‚ค๋ฐฑ๊ณผ, ์šฐ๋ฆฌ ๋ชจ๋‘์˜ ๋ฐฑ๊ณผ์‚ฌ์ „. ์ปดํ“จํ„ฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด ๋””์ž์ธ์—์„œ, ์ผ๊ธ‰ ๊ฐ์ฒด(์˜์–ด: first-class object)๋ž€ ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค์— ์ผ๋ฐ˜์ ์œผ๋กœ ์ ์šฉ ๊ฐ€๋Šฅํ•œ ์—ฐ์‚ฐ์„ ๋ชจ๋‘ ์ง€์›ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค. ๋ณดํ†ต

ko.wikipedia.org

์ฝ”ํ‹€๋ฆฐ์—์„œ๋Š” ํ•จ์ˆ˜๋ฅผ ์ผ๊ธ‰ ๊ฐ์ฒด(First-class object)๋กœ ์ทจ๊ธ‰ํ•œ๋‹ค. ์ฝ”ํ‹€๋ฆฐ์—์„œ ํ•จ์ˆ˜๋ฅผ ์ผ๊ธ‰ ๊ฐ์ฒด๋กœ ์ทจ๊ธ‰ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ํ•จ์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค๊ณผ ๋™๋“ฑํ•˜๊ฒŒ ๋‹ค๋ฃจ์–ด์ง€๊ณ , ๋‹ค์–‘ํ•œ ์—ฐ์‚ฐ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ–๋Š”๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด, ํ•จ์ˆ˜์˜ ๋ฐ์ดํ„ฐ ํƒ€์ž… ๋˜ํ•œ ์กด์žฌํ•  ๊ฒƒ์ด๋‹ค. val s : String์—์„œ s๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด String์ธ ๊ฐ์ฒด์ธ ๊ฒƒ์ฒ˜๋Ÿผ, ์ด String์˜ ์—ญํ• ์„ ํ•˜๋Š” ํ•จ์ˆ˜ ๋ฒ„์ „ ํƒ€์ž… ๋ง์ด๋‹ค.

 

#2 ํ•จ์ˆ˜ ํƒ€์ž… ํ‘œํ˜„์‹์˜ ๋ฌธ๋ฒ•

#2-1 ๊ธฐ๋ณธ ๋ฌธ๋ฒ•

fun myFunction(value1: Int, value2: Int): Int {
    return value1 * value2 + 8
}

fun main() {
    val functionReference: (Int, Int) -> Int

    // ๋”๋ธ”์ฝœ๋ก (::)์€ ์ฝ”ํ‹€๋ฆฐ์—์„œ ํ•จ์ˆ˜, ํด๋ž˜์Šค, ๋ฉค๋ฒ„ ํ•จ์ˆ˜, ์ƒ์„ฑ์ž ๋“ฑ์„ ์ฐธ์กฐํ•˜๋Š” ๋ฐ์— ์‚ฌ์šฉํ•˜๋Š” ๊ธฐํ˜ธ
    functionReference = ::myFunction 

    println(functionReference(7, 9)) // ์ถœ๋ ฅ ๊ฒฐ๊ณผ: 71
}

ํ•จ์ˆ˜ ํƒ€์ž…(Function types) ํ‘œํ˜„์‹์€ (๋งค๊ฐœ๋ณ€์ˆ˜'๋“ค') -> ๋ฆฌํ„ด ํƒ€์ž…์˜ ํ˜•ํƒœ๋กœ ํ•จ์ˆ˜์˜ input๊ณผ output๋ฅผ ๊ธฐ์ˆ ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด val f : (Int, Int) -> Int์—์„œ f๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ Int, String์„ ๋ฐ›๊ณ  return ํƒ€์ž…์€ Int์ธ ํ•จ์ˆ˜๋‹ค. ๋งŒ์•ฝ ์œ„ ์ฝ”๋“œ์—์„œ functionReference์˜ ํ•จ์ˆ˜ ํƒ€์ž… ํ‘œํ˜„์‹์ด myFunction๊ณผ ๋‹ฌ๋ž๋‹ค๋ฉด myFunction์„ ์ฐธ์กฐํ•  ์ˆ˜ ์—†์—ˆ์„ ๊ฒƒ์ด๋‹ค.

 

#2-2 ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ

val functionReference: () -> Int

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†๋‹ค๋ฉด ()์™€ ๊ฐ™์ด ํ•จ์ˆ˜ ํƒ€์ž… ํ‘œํ˜„์‹์˜ ๊ด„ํ˜ธ ์•ˆ์— ์•„๋ฌด๊ฒƒ๋„ ๋„ฃ์ง€ ์•Š์œผ๋ฉด ๋œ๋‹ค.

 

#2-3 return์„ ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ

val functionReference: (Int, Int) -> Unit

ํ•จ์ˆ˜ ํƒ€์ž… ํ‘œํ˜„์‹์—์„œ ํ•จ์ˆ˜์˜ return์ด ์—†๋Š” ๊ฒฝ์šฐ return ํƒ€์ž… ์ž๋ฆฌ์— Unit์„ ๋„ฃ๋Š”๋‹ค. Unit์€ ์ž๋ฐ”์˜ void์— ๋Œ€์‘๋˜๋Š” ํ‚ค์›Œ๋“œ๋‹ค.

 

#2-4 ๋งค๊ฐœ๋ณ€์ˆ˜๋„ ์—†๊ณ  return๋„ ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ

val functionReference: () -> Unit

๋งค๊ฐœ๋ณ€์ˆ˜๋„ ์—†๊ณ , return๋„ ์—†๋‹ค๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜๋Š” () -> Unit ํƒ€์ž…์ด๋‹ค.

 

#1์—์„œ ์ฝ”ํ‹€๋ฆฐ์—์„œ ํ•จ์ˆ˜๋ฅผ ์ผ๊ธ‰ ๊ฐ์ฒด๋กœ ์ทจ๊ธ‰ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ํ•จ์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค๊ณผ ๋™๋“ฑํ•˜๊ฒŒ ๋‹ค๋ฃจ์–ด์ง€๊ณ , ๋‹ค์–‘ํ•œ ์—ฐ์‚ฐ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ–๋Š”๋‹ค๊ณ  ํ–ˆ์—ˆ๋‹ค. ๋‹ค์Œ์œผ๋ก  ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค๊ณผ ๋™๋“ฑํ•˜๊ฒŒ ๋‹ค๋ฃฐ ๋•Œ ํ–‰ํ•ด์ง€๋Š” ๋‹ค์–‘ํ•œ ์—ฐ์‚ฐ์˜ ์˜ˆ์ด๋‹ค.

 

#3 ํ•จ์ˆ˜ ๊ฐ์ฒด ์—ฐ์‚ฐ

#3-1 ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Œ

val functionReference: (Int) -> Int = fun(args: Int): Int {
    return args + 1
}

fun main() {
    val result = functionReference(2)
    println(result) // ์ถœ๋ ฅ ๊ฒฐ๊ณผ: 3
}

/* ์œ„ ์ฝ”๋“œ์™€ ๊ฐ™์€ ๋™์ž‘์„ ํ•˜๋Š” ๋žŒ๋‹ค์‹ ๋ฒ„์ „ ์ฝ”๋“œ
val functionReference: (Int) -> Int = { args -> args + 1 }

fun main() {
    val result = functionReference(2)
    println(result)
}
*/

#2-1์˜ ์ฝ”๋“œ์—์„œ์ฒ˜๋Ÿผ ๋ณ€์ˆ˜์— ํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฝ”ํ‹€๋ฆฐ์—์„œ ์–ด๋–ค ํ•จ์ˆ˜๋ฅผ ์ต๋ช… ํ•จ์ˆ˜๋กœ ์“ฐ๋ฉด์„œ ํ•ด๋‹น ํ•จ์ˆ˜์— ์ด๋ฆ„์„ ๋ถ™์ด๋ฉด ์—๋Ÿฌ(Anonymous functions with names are prohibited)๊ฐ€ ๋‚˜๋ฏ€๋กœ fun ํ‚ค์›Œ๋“œ ์˜ค๋ฅธ์ชฝ์— ํ•จ์ˆ˜ ์ด๋ฆ„์„ ์“ฐ์ง€ ์•Š์•˜๋‹ค.

 

#3-2 ํ•จ์ˆ˜๋ฅผ returnํ•  ์ˆ˜ ์žˆ์Œ

fun add(x: Int, y: Int): Int = x + y

fun getAddFunction(): (Int, Int) -> Int {
    return ::add
}

fun main() {
    val submit = getAddFunction()(2, 3)
    println(submit) // ์ถœ๋ ฅ ๊ฒฐ๊ณผ: 5
}

getAddFunction()์˜ return ํƒ€์ž…์€ Intํ˜• 2๊ฐœ๋ฅผ ๋ฐ›์•„ Int๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” 'ํ•จ์ˆ˜'๋‹ค.

 

#3-3 ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌ ๊ฐ€๋Šฅ

fun calculateNumbers(x: Int, y: Int, operation: (Int, Int) -> Int): Int {
    return operation(x, y)
}

fun main() {
    val result = calculateNumbers(4, 5, fun(args1, args2): Int { return args1 * args2 })
    println(result) // ์ถœ๋ ฅ ๊ฒฐ๊ณผ: 20
}

/* ์œ„ ์ฝ”๋“œ์™€ ๊ฐ™์€ ๋™์ž‘์„ ํ•˜๋Š” ๋žŒ๋‹ค์‹ ๋ฒ„์ „ ์ฝ”๋“œ
fun calculateNumbers(x: Int, y: Int, operation: (Int, Int) -> Int): Int {
    return operation(x, y)
}

fun main() {
    val result = calculateNumbers(4, 5) { args1, args2 -> args1 * args2 }
    println(result)
}
*/

#3-1์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์ธ์ž๋กœ ์ „๋‹ฌ๋˜๋Š” ์ต๋ช… ํ•จ์ˆ˜์˜ ์ด๋ฆ„์„ ๋บ๋‹ค.

 

#4 ์š”์•ฝ

ํ•จ์ˆ˜๋ฅผ ์ผ๋ฐ˜ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด์ฒ˜๋Ÿผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๋‹น์—ฐํžˆ ํ•จ์ˆ˜์˜ '๋ฐ์ดํ„ฐ ํƒ€์ž…' ๋˜ํ•œ ์กด์žฌํ•ด์•ผ ํ•œ๋‹ค.