김완기

김완기

BE Developer

© 2021

Dark Mode

[Kotlin] 코틀린 기초

코틀린 빌드 과정

코틀린 빌드 과정


코틀린 컴파일러로 컴파일한 코드는 코틀린 런타임 라이브러리에 의존한다. 런타임 라이브러리에는 코틀린 자체 표준 라이브러리 클래스와 코틀린에서 자바 API의 기능을 확장한 내용이 들어있다. 코틀린으로 컴파일한 애플리케이션을 배포할 때는 런타임 라이브러리도 함께 배포해야 한다. 실제로 개발을 진행할 때, Maven과 Gradle은 애플리케이션을 패키징 하면서 알아서 코틀린 런타임을 포함시켜 준다.

함수와 변수

Hello, World

fun main(args: Array<String>){
    println("Hello, world!")   
}
  • 함수를 선언할 때 fun 키워드를 사용한다.(fun main)
  • 파라미터 이름 뒤에 그 파라미터의 타입을 쓴다. 변수 선언도 마찬가지이다.(args: Array)
  • 함수를 최상위 수준에 정의할 수 있다.(자바와 달리 꼭 클래스 안에 함수를 넣어야 할 필요가 없다.)
  • 배열도 일반적인 클래스와 마찬가지다. 코틀린에는 자바와 달리 배열 처리를 위한 문법이 따로 존재하지 않는다.
  • System.out.println 대신에 println이라고 쓴다. 코틀린 표준 라이브러리는 여러 가지 표준 자바 라이브러리 함수를 간결하게 사용할 수 있게 감싼 래퍼를 제공한다.
  • 최신 프로그래밍 언어 경향과 마찬가지로 줄 끝에 세미콜른(;)을 붙이지 않아도 된다.


max 함수

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

이 하나의 함수를 까보면 아래와 같다.

  • 함수 이름: max
  • 파라미터 목록: (a: Int, b: Int)
  • 반환 타입: Int
  • 함수 본문: return if(a > b) a else b

여기서 특이한 점은 코틀린 if는 (값을 만들어내지 못하는) 문장이 아니고 결과를 만드는 식이라는 점이다. 그래서 위와 같은 함수 본문은 (a > b) ? a : b 와 같은 3항 연산자와 비슷하다.

코틀린에서 if는 식(expression)이지 문(statement)이 아니다. 
식은 값을 만들어 내며 다른 식의 하위 요소로 계산에 참여할 수 있는 반면 문은 자신을 둘러싸고 있는 가장 안쪽 블록의 최상위 요소로 존재하며 아무런 값을 만들어내지 않는다는 차이가 있다. 
자바에서는 모든 제어 구조가 문인 반면 코틀린에서는 루프를 제외한 대부분의 제어 구조가 식이다. 
제어 구조를 다른 식으로 엮어낼 수 있으면 여러 일반적인 패턴을 아주 간결하게 표현할 수 있다.
반면 대입문은 자바에서는 식이었으나 코틀린에서는 문이 됐다. 


식이 본문인 max 함수

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

조금 전에 살펴본 함수를 더 간결하게 표현하여, 중괄호를 없애고 return을 제거하면서 등호(=)를 식 앞에 붙이면 더 간결하게 함수를 표현할 수 있다. 코틀린에서는 식이 본문인 함수가 자주 쓰인다. 그런 함수의 본문 식에는 단순한 산술식이나 함수 호출 식뿐 아니라 if, when, try 등의 더 복잡한 식도 자주 쓰인다.


더욱 간략한 max 함수

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

위와 같이 반환 타입을 생략하면 더욱 간략하게 만들 수 있다. 코틀린은 정적 타입 지정 언어이므로 컴파일 시점에 모든 식의 타입을 지정해야 하지 않는가? 실제로 모든 변수나 모든 식에는 타입이 있으며, 모든 함수는 반환 타입이 정해져야 한다. 하지만 식이 본문인 함수의 경우 굳이 사용자가 반환 타입을 적지 않아도 컴파일러가 함수 본문 식을 분석해서 식의 결과 타입을 함수 반환 타입으로 정해준다. 이렇게 컴파일러가 타입을 분석해 프로그래머 대신 프로그램 구성 요소의 타입을 정해주는 기능을 타입 추론(type inference)이라고 한다. 주의할 점은 식이 본문인 함수의 반환 타입만 생략 가능하다는 점이다.


변경 가능한 변수와 변경 불가능한 변수

  • val(값을 뜻하는 value에서 따옴): 변경 불가능한(immutable) 참조를 저장하는 변수이다. val로 선언된 변수는 일단 초기화하고 나면 재대입이 불가능하다. 자바로 치면 final에 해당한다.
  • var(변수를 뜻하는 variable에서 따옴): 변경 가능한(mutable) 참조다. 이런 변수의 값은 바뀔 수 있다. 자바의 일반 변수에 해당한다.


변수 선언

val answer: Int = 42
val answer = 42 //타입을 지정하지 않으면 컴파일러가 초기화 식을 분석해서 초기화 식의 타입을 변수 타입으로 지정한다

/* val 참조 자체는 불변일지라도 그 참조가 가리키는 객체의 내부 값은 변경될 수 있다 */
val languages = arrayListOf("Java")
languages.add("Kotlin")


참고: Kotlin in Action