Notice
Recent Posts
Recent Comments
Link
250x250
반응형
«   2025/12   »
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
Archives
Today
Total
관리 메뉴

백고등어 개발 블로그

코틀린 강의 4강: 함수와 람다 표현식 본문

코틀린 강의

코틀린 강의 4강: 함수와 람다 표현식

백고등어 2025. 10. 28. 17:37
728x90
반응형

4강: 함수와 람다 표현식

함수 선언

코틀린에서 함수는 fun 키워드로 선언합니다.

기본 함수

fun greet(name: String): String {
    return "안녕하세요, $name님!"
}

fun main() {
    val message = greet("김코틀린")
    println(message)  // 출력: 안녕하세요, 김코틀린님!
}

단일 표현식 함수

함수 본문이 단일 표현식인 경우 중괄호와 return을 생략할 수 있습니다:

fun add(a: Int, b: Int): Int = a + b

// 반환 타입도 생략 가능 (타입 추론)
fun multiply(a: Int, b: Int) = a * b

fun main() {
    println(add(3, 5))       // 8
    println(multiply(4, 6))  // 24
}

Unit 반환 타입

반환값이 없는 함수는 Unit을 반환합니다. 자바의 void와 유사하지만, Unit은 실제 객체입니다. Unit 반환 타입은 생략 가능합니다:

fun printSum(a: Int, b: Int): Unit {
    println("$a + $b = ${a + b}")
}

// Unit 생략
fun printProduct(a: Int, b: Int) {
    println("$a × $b = ${a * b}")
}

매개변수

기본 인자(Default Arguments)

매개변수에 기본값을 설정할 수 있습니다:

fun greet(name: String, greeting: String = "안녕하세요") {
    println("$greeting, $name님!")
}

fun main() {
    greet("김코틀린")                    // 안녕하세요, 김코틀린님!
    greet("이자바", "반갑습니다")        // 반갑습니다, 이자바님!
}

명명된 인자(Named Arguments)

인자 이름을 명시하여 순서와 관계없이 전달할 수 있습니다:

fun createProfile(name: String, age: Int, city: String) {
    println("이름: $name, 나이: $age, 도시: $city")
}

fun main() {
    createProfile(age = 25, name = "김코틀린", city = "서울")
    createProfile("이자바", city = "부산", age = 30)
}

가변 인자(Vararg)

가변 개수의 인자를 받을 수 있습니다:

fun sum(vararg numbers: Int): Int {
    var result = 0
    for (num in numbers) {
        result += num
    }
    return result
}

fun main() {
    println(sum(1, 2, 3))           // 6
    println(sum(1, 2, 3, 4, 5))     // 15
    
    // 배열을 가변 인자로 전달 (spread 연산자 사용)
    val nums = intArrayOf(1, 2, 3, 4)
    println(sum(*nums))             // 10
}

고차 함수(Higher-Order Functions)

함수를 매개변수로 받거나 반환할 수 있는 함수를 고차 함수라고 합니다.

fun operation(a: Int, b: Int, op: (Int, Int) -> Int): Int {
    return op(a, b)
}

fun main() {
    val add = { x: Int, y: Int -> x + y }
    val multiply = { x: Int, y: Int -> x * y }
    
    println(operation(5, 3, add))      // 8
    println(operation(5, 3, multiply)) // 15
}

람다 표현식

람다는 익명 함수를 간결하게 표현하는 방법입니다.

기본 문법

// 람다 표현식: { 매개변수 -> 본문 }
val sum = { a: Int, b: Int -> a + b }
println(sum(3, 5))  // 8

// 타입 추론 가능
val multiply: (Int, Int) -> Int = { a, b -> a * b }
println(multiply(4, 6))  // 24

단일 매개변수

매개변수가 하나인 경우 it으로 참조할 수 있습니다:

val numbers = listOf(1, 2, 3, 4, 5)

// it 사용
val doubled = numbers.map { it * 2 }
println(doubled)  // [2, 4, 6, 8, 10]

// 명시적 매개변수 이름
val tripled = numbers.map { num -> num * 3 }
println(tripled)  // [3, 6, 9, 12, 15]

후행 람다(Trailing Lambda)

함수의 마지막 매개변수가 람다인 경우, 괄호 밖으로 빼낼 수 있습니다:

val numbers = listOf(1, 2, 3, 4, 5)

// 일반적인 방식
numbers.filter({ it > 2 })

// 후행 람다
numbers.filter() { it > 2 }

// 괄호 생략 (람다가 유일한 인자인 경우)
numbers.filter { it > 2 }

확장 함수(Extension Functions)

기존 클래스에 새로운 함수를 추가할 수 있습니다:

// String 클래스에 함수 추가
fun String.lastChar(): Char {
    return this[this.length - 1]
}

fun Int.isEven(): Boolean {
    return this % 2 == 0
}

fun main() {
    println("Kotlin".lastChar())  // n
    println(4.isEven())            // true
    println(5.isEven())            // false
}

중위 함수(Infix Functions)

infix 키워드를 사용하면 점(.)과 괄호 없이 함수를 호출할 수 있습니다:

infix fun Int.add(other: Int): Int {
    return this + other
}

fun main() {
    println(5 add 3)    // 8
    println(5.add(3))   // 8 (일반 호출도 가능)
}

코틀린 표준 라이브러리의 많은 함수가 중위 함수로 정의되어 있습니다:

val map = mapOf(1 to "one", 2 to "two", 3 to "three")
// to는 중위 함수입니다

지역 함수(Local Functions)

함수 내부에 다른 함수를 정의할 수 있습니다:

fun calculatePrice(quantity: Int, price: Double): Double {
    fun applyDiscount(total: Double): Double {
        return when {
            total > 100000 -> total * 0.9
            total > 50000 -> total * 0.95
            else -> total
        }
    }
    
    val total = quantity * price
    return applyDiscount(total)
}

fun main() {
    println(calculatePrice(100, 1200.0))  // 108000.0 (10% 할인)
}

실용적인 예제

filter, map, reduce 활용

fun main() {
    val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    // 짝수만 필터링
    val evens = numbers.filter { it % 2 == 0 }
    println(evens)  // [2, 4, 6, 8, 10]
    
    // 각 요소를 제곱
    val squares = numbers.map { it * it }
    println(squares)  // [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    
    // 체이닝
    val result = numbers
        .filter { it % 2 == 0 }
        .map { it * it }
        .sum()
    println(result)  // 220
}

함수형 프로그래밍 스타일

data class Person(val name: String, val age: Int)

fun main() {
    val people = listOf(
        Person("김철수", 25),
        Person("이영희", 30),
        Person("박민수", 22),
        Person("최지원", 35)
    )
    
    // 30세 이상인 사람의 이름
    val adults = people
        .filter { it.age >= 30 }
        .map { it.name }
    println(adults)  // [이영희, 최지원]
    
    // 평균 나이
    val averageAge = people.map { it.age }.average()
    println("평균 나이: $averageAge")  // 28.0
    
    // 가장 나이가 많은 사람
    val oldest = people.maxByOrNull { it.age }
    println("최고령자: ${oldest?.name}")  // 최지원
}

마치며

이번 강의에서는 코틀린의 함수와 람다 표현식에 대해 알아보았습니다. 고차 함수와 람다를 활용하면 간결하고 표현력 있는 코드를 작성할 수 있습니다. 확장 함수를 사용하면 기존 클래스의 수정 없이 기능을 추가할 수 있다는 점도 기억하세요. 다음 강의에서는 클래스와 객체지향 프로그래밍에 대해 알아보겠습니다.

728x90
반응형