코틀린
Kotlin,
통합 개발환경인 인텔리 J로 유명한 제트브레인에서 내놓은 프로그래밍 언어. 자바 가상머신 위에서 동작하며 자바와 100% 호환된다는 것이 제트브레인 측의 설명이다. 즉 자바가 돌아가는 환경이라면 코틀린도 돌아간다. 그 대표적인 예가 안드로이드로, 지금도 코틀린을 사용해서 안드로이드 프로그래밍을 하는 것이 가능하며[1] 안드로이드 스튜디오 3.0부터는 아예 자바와 함께 코틀린도 지원한다. 물론 자바 라이브러리도 제약 없이 갖다 쓸 수 있다.
특징
간결함
자바에 비해서 훨씬 간결하게 코드를 짤 수 있으며, 현대 프로그래밍의 여러 개념들을 적극 수용했다. 실제로 똑같은 일을 하는 프로그램을 자바와 코틀린으로 짜 보면 코틀린의 코드 양이 훨씬 적다. 예를 들면 아래의 코드는 단 한 줄로 name, email, company 세 개의 필드를 가지고 이에 대한 getters와 setters는 물론 equals(), hashCode(), toString() 그리고 copy()까지 모두 지원하는 POJO 클래스를 정의한다.
data class Customer(val name: String, val email: String, val company: String)
이걸 자바로 짜려면 몇 줄이나 나올까? 말도 하지 말자. 그런데 자세히 보면 변수 혹은 매개변수를 정의하는 방법이 자바와 많이 다르다. val이라는 키워드가 먼저 나오고, 변수 이름이 나온 다음 콜론을 찍고 변수의 타입을 쓴다. 변수 타입 → 이름 순서인 자바[2]와는 반대다. [3]
또한 과도하게 엄격한 예외 처리를 강요하는 자바와는 달리 모든 예외 처리를 강제하지 않는다. 모든 예외를 다 프로그래밍으로 처리함으로써 오류 문제에 단단한 코드를 만들려고 했던 게 자바지만 지나친 엄격함에 시달리다 못해 그냥 안 받아도 되는 RuntimeException 같은 걸로 다 때워버리든가 해버려서 오히려 프로그램을 부실하게 만드는 자바의 문제점을 해소한 셈이다.
자바와는 달리 줄 끝에 세미콜론을 쓰지 않는 것도 차이. 요즘 인기 있는 언어들인 파이썬, Go(응?), 스위프트도 역시 줄끝에 세미콜론을 쓰지 않는다.
안전함
코틀린이 강조하는 또 하나의 특징은 안전함이다. 코틀린은 null 값이 들어가도 되는 변수(nullable)와 그렇지 않은 변수를 구분한다. 기본은 nullable이 아니며 nullable로 지정하려면 변수의 타입 뒤에 ? 기호를 붙여 줘야 한다. 이로 인해 null 값을 잘못 사용해서 생길 수 있는 문제[4]를 컴파일 단계에서 더 많이 잡아준다.
var output: String
output = null // Compilation error
val name: String? = null // Nullable type
println(name.length()) // Compilation error
현대적
최근에 유행하는 고차함수나 클로저, 람다식 같은 개념들을 지원한다. 자바도 버전 8부터는 클로저나 람다식을 지원하지만 사용하려면 좀 복잡한데, 코틀린으로 하면 훨씬 간단하다.
fun <T> lock(lock: Lock, body: () -> T): T {
lock.lock()
try {
return body()
}
finally {
lock.unlock()
}
}
고차함수의 예. lock 함수의 두 번째 매개변수는 body: () -> T
로 되어 있는데, 이는 매개변수가 없고 T 유형의 반환값을 가지는 함수를 매개변수로 받는다는 뜻이며, 함수 안에서는 이를 body
로 참조해서 실행시킬 수 있다.
기본 문법
일단 기본적인 문법은 다음과 같다.
변수 선언
변수를 선언하려면 var, 또는 val 키워드를 사용한다. val은 한번 선언하고 초기값을 부여하면 변경할 수 없는, 즉 읽기만 가능한 변수이고, var는 값을 변경할 수 있는 변수다. 가장 기본이 되는 형식은 다음과 같다.
// val [변수 이름]:[변수 타입] = [대입할 값]
// var [변수 이름]:[변수 타입] = [대입할 값]
var num: Integer
val num: Integer = 1
하지만 대입값에 따라서 추측하는 기능이 있어서 타입을 안 쓸 수도 있다.
val name = "John Doe" // name은 자동으로 String 타입이 된다.
name = 1 // Error!
val unknown // Error!
주의할 것은, 파이썬처럼 name에 다른 타입의 값을 집어넣을 수 없다. 선언 시점에서 초기 대입값에 따라 변수 타입이 결정되므로 다른 타입의 값을 넣으려고 하면 컴파일 단계에서 오류가 난다. 또한 변수를 선언만 하고 초기 대입값이 없으면 타입을 추정할 수 없으므로 이 역시 에러가 난다.
기본적으로 코틀린의 변수에는 null을 대입할 수 없다. null을 대입하려면 반드시 타입 뒤에 ? 표시를 붙여줘야 한다.
val he: String = "John Doe" // non-nullable
val she: String? = "Jane Doe" // nullable
he = null // Error!
she = null // Okay.
함수 선언
함수를 선언하려면 fun 키워드를 사용한다. 함수는 즐겁다. 변수 선언 때처럼 반환값 타입을 함수 매개변수 정의 뒤 : 다음에 써야 한다.
fun sum(a: Int, b: Int): Int {
return a + b
}
// 위 함수를 다음과 같이 축약할 수도 있다.
fun sum(a: Int, b: Int): Int = a + b
클래스와 객체
확장
기존 클래스에 새로운 메서드를 넣고 싶다면 자바에서는 클래스를 상속 받아서 추가해야 했다. 코틀린은 그럴 필요 없이 그냥 기존 클래스를 확장해서 새로운 메서드를 추가할 수 있는 방법을 제공한다.
각주
- ↑ 안드로이드 스튜디오에서 코틀린 플러그인을 설치해서 쓸 수 있다.
- ↑ 자바만이 아니라 대부분 언어가 그렇다. 반면 Go는 코틀린처럼 변수의 타입을 나중에 쓴다. 이쪽을 지지하는 주장은 보통 사람은 '변수 name은 String 유형'와 같은 순서로 생각하는 게 자유롭다는 것.
- ↑ 코틀린의 변수 선언과 가장 비슷한 언어는 놀랍게도 지금 별로 쓰이지 않고 있는 파스칼이다! 코틀린의 변수 선언 방식은
val a: Int = 10000
인데 파스칼도var a : integer = 10000;
. - ↑ 이른바 The Billion Dollar Mistake라고 부른다.