Skip to content
ioob.dev
Go back

Kotlin 입문 3편 — 함수

· 3분 읽기

Table of contents

함수 선언

Kotlin의 함수는 fun 키워드로 선언한다.

fun greet(name: String): String {
    return "Hello, $name!"
}

반환 타입은 콜론 뒤에 쓴다. 반환값이 없으면 Unit인데, 생략할 수 있다. Java의 void에 해당한다.

fun log(message: String) {  // : Unit 생략됨
    println(message)
}

기본값 파라미터

Java에서 메서드 오버로딩을 남발해본 경험이 있다면, Kotlin의 기본값 파라미터가 반가울 것이다.

fun createUser(
    name: String,
    age: Int = 0,
    role: String = "user"
): String {
    return "$name ($age, $role)"
}

이 함수 하나로 여러 방식의 호출이 가능하다.

createUser("Kim")                      // Kim (0, user)
createUser("Lee", 25)                  // Lee (25, user)
createUser("Park", 30, "admin")        // Park (30, admin)

Java였다면 파라미터 조합마다 오버로딩 메서드를 만들어야 했을 것이다. Kotlin은 기본값 하나로 해결된다.

Named Argument

파라미터가 많아지면 호출부에서 어떤 값이 어떤 파라미터인지 헷갈리기 쉽다. Named argument를 쓰면 명확해진다.

createUser(
    name = "Kim",
    role = "admin",  // age를 건너뛰고 role만 지정
)

중간 파라미터를 건너뛸 수 있다는 게 핵심이다. 기본값 파라미터와 조합하면 빌더 패턴 없이도 유연한 객체 생성이 가능해진다.

단일 표현식 함수

함수 본문이 표현식 하나로 끝나면, 중괄호와 return을 생략할 수 있다.

// 일반 형태
fun double(x: Int): Int {
    return x * 2
}

// 단일 표현식 — 같은 함수를 한 줄로
fun double(x: Int) = x * 2

반환 타입도 추론되기 때문에 생략 가능하다. 간단한 변환 함수나 유틸리티 함수에서 자주 쓴다.

다만 로직이 복잡해지면 가독성이 떨어지니, 한 줄에 자연스럽게 들어가는 경우에만 쓰는 게 좋다.

확장 함수

Kotlin에서 가장 독특한 기능 중 하나다. 기존 클래스를 상속하거나 수정하지 않고, 외부에서 메서드를 추가할 수 있다.

// String에 isEmail 함수를 추가
fun String.isEmail(): Boolean {
    return this.contains("@") && this.contains(".")
}

fun main() {
    println("test@email.com".isEmail())  // true
    println("not-email".isEmail())        // false
}

String.isEmail()이라고 쓰면, 마치 String 클래스에 원래 있던 메서드처럼 호출할 수 있다. this는 호출된 객체 자신을 가리킨다.

실무에서 활용되는 예를 하나 더 보자.

// Int에 원(₩) 포맷을 추가
fun Int.toWon(): String {
    return "₩${String.format("%,d", this)}"
}

fun main() {
    println(50000.toWon())     // ₩50,000
    println(1234567.toWon())   // ₩1,234,567
}

확장 함수는 원본 클래스의 private 멤버에는 접근할 수 없다. 실제로 내부적으로는 정적 메서드로 컴파일되기 때문에, 기존 클래스의 캡슐화를 깨뜨리지 않는다.

Android 개발이나 Spring 프로젝트에서 유틸리티 함수를 만들 때 특히 유용하다. StringUtils.isEmpty(str) 대신 str.isEmpty()처럼 자연스러운 코드를 작성할 수 있기 때문이다.


다음 편에서는 Kotlin의 클래스와 객체를 다룬다. data class가 보일러플레이트를 얼마나 줄여주는지, object는 어떤 역할을 하는지 살펴보자.

4편: 클래스와 객체


Share this post on:

Comments

Loading comments...


Previous Post
Kotlin 입문 4편 — 클래스와 객체
Next Post
Kotlin 입문 2편 — 조건문과 반복문