Kotlin 개요

Kotlin이란?

Kotlin(코틀린)는 IntelliJ IDEA 등의 IDE (Integrated Development Environment: 통합 개발 환경) 로 유명한 JetBrains가 중심이 되어 개발이 진행되고 있는 새로운 프로그래밍 언어이다. 2011년 여름에 발표되어 현재 Apache 2.0 라이센스로 OSS(Open Source Software)로서 개발 환경과 그 소스 코드가 공개되어 무료로 사용할 수 있다.

Kotlin으로 작성된 코드는 JVM(Java Virtual Machine : Java 가상 머신)에서 실행되는 Java 바이트 코드 (친숙한 클래스 파일)로 컴파일된다. 이러한 프로그래밍 언어를 JVM 언어 라고 부른다. Scala와 Groovy도 Kotlin과 마찬가지로 JVM 언어 중 하나이다. 그리고 JavaScript로의 컴파일도 서포트하고 있는 altJS의 하나이기도 한다. Android 앱 개발도 지원한다.

Kotlin은 형식 추론과 람다식, 트레이트 등의 현대적인 문법, 기능을 가진 정적 형식화의 본격적인 객체 지향 언어이다. Java보다 간결하고 안전한 코드를 작성하는 것이 특징이다.

2016년 2월에 v1.0이 출시되었고, 2017년 5월에 구글 I/O 행사에서 안드로이드의 공식 언어로 코틀린으로 발표하였다. 그리고 Spring 프레임워크도 2016년 스프링 블로그에 Developing Spring Boot applications with Kotlin 내용이 올라왔고, 2017년 1월에 스프링 프레임워크 5.0이 코틀린을 지원할 것이라고 소개하였다.

참고로 JetBrains는 러시아와 체코 출신 개발자로 구성되어 있으며, Kotlin은 러시아에 위치한 섬의 이름이다.

왜 Kotlin을 사용해야 하는가?

세상에는 프로그래밍 언어가 이미 셀 수 없을 정도로 많이 존재한다. 그 중에서 왜 Kotlin 이어야 하는지 알아보자!

먼저 말할 수 있는 것은 JVM 언어라는 것이다. Java는 전세계에서 사용되는 매우 인기있는 언어이다. 1995년에 등장한 이래로 많은 코드가 작성 되었고 많은 시스템이 운영되어 왔다. 자바는 지금도 진화를 계속하고 있다. 그러나 그 반면에 하위 호환성(backward compatibility)을 유지하기 위해서 기술의 중복이나 타입 안전성의 문제는 개선 되기에 어려움 존재한다. 그래서 JVM 언어의 등장하게 되었다. Java가 안고 있는 문제로부터 해방되어 프로그래밍할 수 있을 뿐만 아니라, 높은 신뢰와 성능을 가진 JVM 에서 동작하고, Java에 의해 기술된 기존의 라이브러리/프레임워크 등의 자산을 활용할 수 있는 등의 이점도 갖게 있다.

JVM 언어만으로도 그 수는 매우 많다. 유명한 것으로는 Scala와 Groovy가 있으며, 이런 경쟁 속에서 JetBrains는 다음과 같은 Kotlin의 설계 목표를 정하고 있다.

  • Java 호환
  • 적어도 Java와 동등한 컴파일 속도
  • Java보다 높은 안전성 : null 포인터 역참조(dereference)와 같은 흔한 실수에 대한 정적 확인 등
  • Java보다 높은 간결성 : 형 변수의 추론, 고차원 함수(클로저)⁠, 확장 함수, 믹스 인(mixin)이나 1급 델리게이션 등을 지원
  • Scala보다 간단한 방법으로 표현력을 실용적인 수준으로 유지

특징적인 것은, null 포인터 역참조. 즉, NullPointerException이 일어날 수 없는 것 같은 구조(NULL Safe)가 언어 기능으로서 제공되고 있는 점이다. 그 밖에도 실수를 미연에 막아주는 기능이 있어, Java보다도 쉽게 발생하는 버그를 발생하기 어려운 언어가 되고 있다. 안전에 무게를 두면 코드가 복잡해지는 것이 아닐까 하는 걱정이 있을 수 있지만, 그 점도 Kotlin에서는 고려되고 있다. 이러한 특징 외에도 Java와 비슷한 문법으로 학습 비용이 적게 발생하기 때문에 실제 업무에서의 사용에 적합하지 않을까 생각된다.

Kotlin 특징

간결, 안전, Java 바이트 코드와 JavaScript로 컴파일 가능, 정적 형식화, 객체 지향, 클로저 등은 Kotlin을 설명하는 상투적인 문구에 불과하다. 그러나 모두 Kotlin의 특징을 단적으로 나타내는 중요한 말이다. 간단한 코드를 섞어 하나씩 소개한다.

간결하다.

라인 마지막에 세미콜론 불필요, 타입추론, 데이터 클래스, 확장 함수 등

Kotlin 코드 자체의 단순성은 물론 문법 즉, 작성 규칙도 간결하다. 코드가 간결하기 때문에 타이핑하는 횟수가 줄어들고, 오류가 발생하기 어려울 뿐만 아니라, 가독성이 높아 유지보수의 비용 절감을 기대할 수 있다. 그리고 문법이 간결하기 때문에 학습 비용이 적고, 프로그래머의 레벨 차이로 인한 코드의 편차를 줄일 수 있다. 아래 예제 1) 코드는 언제나 익숙한 HelloWorld를 Kotlin으로 작성한 코드이다.

예제 1) Kotlin으로 HelloWorld

package sample

fun main(args: Array<String>) {
  val message = "Hello, world!"
  println(message)
}

CLI의 검은 화면에서 인사말이 표시될 뿐인 간단한 프로그램이지만 Kotiln의 특징을 살펴볼 수 있다. 먼저 최상위 레벨(High-level)에서 함수를 정의할 수 있다는 것을 알 수 있다. fun 키워드는 함수 정의에 필요한 키워드이다. 그리고 main라는 이름으로, Array<String>타입의 인수를 포함 함수가 Kotlin 프로그램의 엔트리 포인트이다. 변수 타입을 변수 이름 뒤에 오는 것도 Java와 다르다.

표시할 메시지를 변수 message에 할당한다. Kotlin에서는 val 키워드(혹은 var)을 사용하여 변수를 선언한다. message는 String 타입이지만, 오른쪽에서 추론할 수 있으므로 명시할 필요가 없다.

println는 인수의 값을 표준 출력에 내보내는 함수이다. 세미콜론(;)을 넣어 문장의 끝에 명시할 필요는 없다. 같은 줄에 계속해서 문장을 쓰는 경우에는 ;으로 구분해야 한다.

이보다 더 간략히 아래와 같이 작성할 수도 있다.

예제 2) 더 간략해진 HelloWorld

package sample

fun main() {
    println("Hello, world!")
}

안전하다.

Null safe : 변수와 함수의 반환 값 등에 nil이 들어갈 가능성이 있는 명시를 해야한다.

앞서 언급했듯이 Kotlin은 Java에 비해 안전하다. 타입이나 null 취급이 엄격하다. 예를 들어, Kotlin에서는 캐스트나 null 역참조에 의한 런타임 예외가 발생하는 것은 매우 드물다.

Kotlin은 null 할당 할 수 있는 변수와 할 수 없는 변수를 구별한다. 아래 예제 3) 코드에서는 bnull을 할당하는 곳에서 컴파일 오류가 발생한다. 일반적인 형태(여기에서는 String)의 변수 null에는 대입할 수 없다.

예제 3) 일반 타입의 변수에는 null을 할당할 수 없다.

val a: String = "Kotlin" // OK
val b: String = null // NG!!

약간 변경된 **예제 4)**은 컴파일에 성공한다. 변수와 d의 타입이 String?으로 되어 있다.

예제 4) ?가 붙은 타입의 변수에는 null을 대입할 수 있다.

val c: String? = "Kotlin" // OK
val d: String? = null // OK

이렇게 ?가 뒤에 붙는 타입의 변수는 null 대입 가능하다. 그러나 변수가 참조하는 객체의 멤버에 대한 액세스에는 제한이 있다. NullPointerException를 방지하고 Null 안전을 위한 것이다. Null 안전에 대해서는 다음번 이후에 다시 설명하도록 하겠다.

자바 바이트 코드와 자바 스크립트로 컴파일 가능

이미 소개했듯이 Kotlin은 JVM 언어이며 컴파일러는 Java 바이트 코드를 컴파일된다. Kotlin 코드에서 Java 코드를 호출 할 수 있을 뿐만 아니라 Java 코드에서 Kotlin 코드를 호출 할 수도 있다. **예제 5)**는 Java 표준 라이브러리를 Kotlin 코드에서 호출하여 텍스트 파일의 내용을 표시하는 예이다.

예제 5) Kotlin에서 Java 표준 라이브러리 사용

import java.nio.file.Files
import java.nio.file.Paths

fun main(args: Array<String>) {
  val path = Paths.get("/memo.txt")
  val lines = Files.readAllLines(path)
  for (line in lines) {
    println(line)
  }
}

또한 컴파일러는 Kotlin 코드를 입력으로 받아 JavaScript 코드를 변환할 수도 있어서 원한다면 백엔드와 프런트 엔드 모두 Kotlin을 사용하여 개발할 수 있다.

정적 타이핑(Static typing) 언어이다.

Kotlin은 컴파일러 언어이다. 이는 단순히 인터프리터 언어보다 실행 속도가 빠르다는 것만을 의미하지는 않는다. 컴파일러는 컴파일 타임에 소스 코드의 오류를 발견하고 실행 코드를 생성하지 않기 때문에 프로그래머는 초기에 버그를 발견하고 안전한 프로그램을 만들 수 있게 된다.

정적 타이핑(Static typing) 프로그래밍 언어는 변수가 사용전에 정의 되어야 할 필요가 없는 프로그래밍 언어를 말한다.

객체 지향 언어이다.

Kotlin은 클래스 기반의 객체 지향 언어이다. Java와 동일하게 정의된 클래스에서 인스턴스를 생성 할 수 있다. **예제 6)**는 클래스를 정의하고 인스턴스를 생성하는 간단한 예이다. 이미 객체 지향 언어를 알고 있는 사람은 친숙한 문법이라고 느낄 것이다.

예제 5) User 클래스의 인스턴스 생성 및 사용

// User 클래스 정이
class User {
  // 프로퍼티
  var id: Long = 0
  var name: String = ""

  // 메서드 오버라이드
  override fun toString(): String {
    return "name=" + name
  }
}

fun main(args: Array<String>) {
  // User 인스턴스 생성
  // new 키워드 기입 불필요
  val user = User()
  user.id = 12345
  user.name = "devkuma"
  println(user.toString()) // => name=devkuma
}

Kotlin에는 Java와 달리 기본형 타입(Primitive type)이 없으며 모든 것이 객체이다. 또, 프로퍼티나 트레이트(trait), 오브젝트 선언 등 Java에는 없는 편리한 기능이 제공되고 있다.

클로저(Closure)

Kotlin에는 일급 객체로서의 함수가 있다. 즉, 함수를 다른 값과 마찬가지로 함수의 인수로 전달하거나 반환 값으로 받을 수 있다. 이로써 보다 세밀한 단위로 함수를 재사용 할 수 있으며 추상적인 프로그래밍이 가능하다. 이것이 Kotlin의 간결하게 하는 방식 중 하나이다.

Kotlin의 표준 라이브러리가 제공하는 Collection Operations API의 예러 예제 7) 를 보도록 하겠다.

예제 7) 함수를 인수로 전달하여 목록을 조작한다.

// 조작 목록 생성
val list = listOf(3, 5, 2, 7, 4)
println(list) // => [3, 5, 2, 7, 4]

// 각 요소를 2를 곱한 목록를 생성
val twice = list.map { e -> e * 2 }
println(twice) // => [6, 10, 4, 14, 8]

// 짝수의 요소로만 필터링된 목록 생성
val even = list.filter { e -> e % 2 == 0 }
println(even) // => [2, 4]

이런 함수는 클로저(Closure)라고 한다. 클로저는 내부에서 참조하는 이외의 변수를 외부에서 캡처하는 함수이다. 코드를 보면서 설명하는 것이 이해하기 쉽기에, 클로저의 상세 설명은 다음 번에 하도록 하겠다.

요약

이번에는 Kotlin의 소개로서 개요와 특징, 간단한 문법을 ​​다뤘다. Kotlin은 JetBrains에서 출발하는 오픈 소스 JVM 언어이다. 그 기능과 문법은 간결함과 안전성을 겸비하고 있다. 객체 지향, 클로저, 타입 안전 등 현대적인 언어에는 있어 원하는 기능은 하나로 갖추고 있다. 특히 NULL 안전은 독특한 메커니즘이다.

다음 번에는 개발 환경을 준비하고 프로그래밍의 예로 실습을 하도록 하겠다.

부록: Kotlin 학습법

Kotlin을 학습하기에 위해서는 여러 방법이 있겠지만, 본인에게 맞는 방법을 찾는게 중요하다. 서적을 선호하는 사람이 있을 수도 있고, 인터넷 사이트 및 블로그를 찾아 보는 것을 좋아하는 사람이 있을 수도 있다. 또는 동영상 강좌를 보려는 사람도 있을 것이다.

개인적으로는 여러 방법을 시도해 보라고 하고 싶다. 간단히 동영상 강좌부터해서 인터넷 페이지를 보고 서적으로 상세히 보면서 언어에 친숙해 지길 바란다. 이는 코틀린 학습에만 유독 해당되지는 않을 것이다. 어떤 학문이던 작은 나무를 먼저 보고 점점 범위를 넓혀 숲 전체를 볼 수 있을 것이다.