안녕하세요. 코틀린 #2

  1. 안녕하세요. 코틀린 #1
  2. 안녕하세요. 코틀린 #2
  3. 안녕하세요. 코틀린 #3

객체 없는 함수

저번 시간에 Hello Realm!을 출력하기 위해 사용했던 코드를 다시 살펴봅시다.

fun main(args: Array<String>) {
    println("Hello Realm!")
}

특이하게 클래스가 없습니다. 자바에서는 모든 함수가 클래스에 속해야 했는데 어떻게 코틀린에서 클래스가 없는 함수가 가능할 수 있을까요? 코를린은 자바 가상 머신에서 실행되는게 아닐까요? 이 의문을 풀기 위해서 실제 이 코드가 어떻게 동작되는지를 확인해봅시다. 커맨드라인에서 kotlin을 실행하기 위해 homebrew를 이용하여 kotlin을 설치합시다.

brew install kotlin

설치가 완료되면 kotlinc를 이용해서 app.kt 파일을 컴파일해봅시다.

kotlinc app.kt
info: PERF: INIT: Compiler initialized in 459 ms
info: PERF: ANALYZE: 1 files (3 lines) in 488 ms
info: PERF: GENERATE: 1 files (3 lines) in 45 ms

이런 개발 뉴스를 더 만나보세요

컴파일이 끝났으면 javap를 이용해서 컴파일된 AppKt 클래스를 살펴봅시다.

javap AppKt
Compiled from "app.kt"
public final class AppKt {
  public static final void main(java.lang.String[]);
}

main의 자세한 내용은 지금은 알 수 없지만 AppKt 클래스 안에 main 스태틱 메서드가 만들어진 것을 볼 수 있습니다. 코틀린에서 간단한 기능들은 메서드만으로 구성할 수 있고 이 메서드들은 파일명을 기준으로 자동으로 클래스가 생성되고 스태틱 메서드가 만들어진다는 것을 알 수 있습니다. 이 클래스들은 이름 뒤에 Kt가 붙기 때문에 클래스 이름 뒤에 Kt를 붙이지 않는 한 기존의 클래스와 충돌되지는 않습니다. main 안의 내용을 알기 위해서는 -c 옵션을 이용하면 볼 수 있습니다. 내부의 내용은 여기서 다룰 범위를 넘어가기 때문에 다루지 않겠습니다.

다양한 방법으로 함수 정의하기

간단한 함수를 정의해보겠습니다.

fun sum(a: Int, b: Int): Int {
  return a + b
}

fun main(args: Array<String>) {
    println("Hello Realm! ${sum(5, 3)}")
}

인텔리제이 환경에서는 이전과 같이 실행하면 됩니다. 만약 커맨드라인에서 수행하고 싶다면 아래와 같이 입력하세요.

kotlinc app.kt -include-runtime -d app.jar
info: PERF: INIT: Compiler initialized in 455 ms
info: PERF: ANALYZE: 1 files (8 lines) in 516 ms
info: PERF: GENERATE: 1 files (8 lines) in 50 ms

먼저 코틀린 런타임을 포함하여 결과물을 jar 파일로 뽑습니다. 그 후에 jar 파일을 수행하면 됩니다.

java -jar app.jar
Hello Realm! 8

반환값을 가진 함수는 반환값을 괄호뒤에 콜론(:)과 함께 붙입니다. sum 함수뒤에도 : Int가 붙어있는 것을 볼 수 있습니다. 이 함수는 main에서 호출되고 있습니다. 문자열 가운데 ${sum(5, 3)}가 있는 것을 볼 수 있는데요. 이는 중괄호 안에 있는 내용 즉 sum(5,3)을 수행한 결과를 문자열에 포함시키라는 것입니다. sum(5, 3)이 수행된 결과 8이 그 자리에 위치하게 되어 Hello Realm! 8이 출력되게 합니다.

호출이 문자열 안에 있으니 번잡하네요. 상수를 이용해서 밖으로 빼겠습니다.

fun sum(a: Int, b: Int): Int {
    return a + b
}

fun main(args: Array<String>) {
    val a = sum(5, 3)
    println("Hello Realm! ${a}")
}

val은 상수를 선언하는 방식입니다. 값을 변경할 수 있는 변수가 필요한 경우에는 var을 사용하면 됩니다. 타입은 자동으로 추론되기 때문에 적지 않았습니다.

굳이 적겠다면 아래와 같이 적을 수 있습니다.

fun sum(a: Int, b: Int): Int {
    return a + b
}

fun main(args: Array<String>) {
    val a: Int = sum(5, 3)
    println("Hello Realm! ${a}")
}

타입을 상수명 뒤에 적어주었습니다.

변수나 상수를 문자열 가운데 출력하고 싶은 경우에는 중괄호를 생략할 수 있습니다.

fun sum(a: Int, b: Int): Int {
    return a + b
}

fun main(args: Array<String>) {
    val a = sum(5, 3)
    println("Hello Realm! $a")
}

상수 이외에 변수를 사용할 수도 있습니다. val 대신에 var를 사용해봅시다.

fun sum(a: Int, b: Int): Int {
    return a + b
}

fun main(args: Array<String>) {
    var a = sum(5, 3)
    println("Hello Realm! $a")
}

sum 함수 자체를 조금 더 짧게 할 방법이 없을까요? 한줄 밖에 없는데 함수 블록을 쓰는 것은 좀 길어 보여요.

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

반환 값만 리턴하는 함수라면 return과 중괄호를 삭제하고 적을 수 있습니다.

반환 값도 추론을 통해 생략할 수 있습니다. 반환 값에 대한 타입 생략은 한줄 함수에서만 가능합니다.

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

아예 함수를 생략하는 방법은 없을까요? 람다를 사용할 수 있습니다.

fun main(args: Array<String>) {
    val a = { a: Int, b: Int -> a + b }(3, 5)
    println("Hello Realm! $a")
}

람다는 중괄호 구문 안에 인자를 적어주고 ->을 적은 다음 반환 값을 뒤에 적어주면 됩니다.

함수에 조건식 사용하기

간단한 max를 함수로 만들어 봅시다.

fun max(a: Int, b: Int): Int {
    if (a > b)
        return a
    else
        return b
}

fun main(args: Array<String>) {
    val value = max(3, 5)
    println("Hello Realm! $value")
}

위의 두개의 리턴이 있지만 모두 하나의 if에 속해있습니다. 이런 경우 코틀린에서는 조건식(conditional expressions)를 사용할 수 있습니다.

fun max(a: Int, b: Int) = if (a > b) a else b

fun main(args: Array<String>) {
    val value = max(3, 5)
    println("Hello Realm! $value")
}

조건문(conditional statements)를 사용할 경우 보다 조금 더 간결하게 코딩할 수 있습니다.

다음으로

다음 시리즈에서는 Null 처리, 타입, 캐스팅, 반복문, range 등을 다루겠습니다.

다음: Kotlin를 마스터하는 길 #3: 안녕하세요. 코틀린 #2

General link arrow white

컨텐츠에 대하여

이 컨텐츠는 저자의 허가 하에 이곳에서 공유합니다.


Leonardo YongUk Kim

Leonardo YongUk Kim is a software developer with extensive experience in mobile and embedded projects, including: several WIPI modules (Korean mobile platform based on Nucleus RTOS), iOS projects, a scene graph engine for Android, an Android tablet, a client utility for black boxes, and some mini games using Cocos2d-x.

4 design patterns for a RESTless mobile integration »

close