함수
1 | fun main(args: Array<String>) { |
문(statement)과 식(expression)
코틀린에서는 루프를 제외한 대부분의 제어 구조가 식이다. 자바에서는 if는 문이지만 코틀린에서는 식인 것처럼 말이다. 여기서 식은 값을 만들어내고 문은 자신을 둘러싸고 있는 가장 안쪽 블록의 최상위 요소로 존재하며 아무런 값을 만들어내지 않는다는 차이가 있다.
1 | fun max(a: Int, b: Int) : Int { |
식이 본문인 함수
코틀린에서는 식이 본문인 함수가 자주 쓰인다. 그런 함수의 본문 식에는 단순한 산술식이나 함수 호출 식뿐 아니라 if, when, try 등의 더 복잡한 식도 자주 쓰인다. 위에서 예제로 보인 식을 조금 더 단순하게 아래와 같이 표현할 수 있다.
1 | fun max(a: Int, b: Int) : Int = if (a > b) a else b |
- 중괄호 삭제
- return 삭제
- 리턴타입 삭제 → 타입 추론 :
식이 본문인 함의 반환 타입만 생략 가능
변수
변경 불가능
자바의 final과 동일하게 값을 뜻하는 value에서 따온 val
키워드를 사용한다. val로 선언된 변수는 일단 초기화하고 나면 재대입이 불가능하다.
val 변수는 블록을 실행할 때 정확히 한 번만 초기화해야 하지만 어떤 블록이 실행될 때 오직 한 초기화 문장만 실행됨을 컴파일러가 확인할 수 있다면 조건에 따라 val 값을 다른 여러 값으로 초기화할 수도 있다.
1 | val message: String |
또한 val 참조 자체는 불변일지라도 그 참조가 가리키는 객체의 내부 값은 변경할 수 있다.
1 | val languages = arrayListOf("Java") |
변경 가능
변수를 뜻하는 variable에서 따온 var
키워드를 사용한다. 이런 변수의 값은 바뀔 수 있으며 자바의 일반 변수에 해당한다.
코틀린에선
기본적으로는 모든 변수를 val
키워드를 사용해 불변 변수로 선언하고, 나중에 꼭 필요할 때에만 var
로 변경하길 권고한다. 변경 불가능한 참조와 변경 불가능한 객체를 부수 효과가 없는 함수와 조합해 사용하면 코드가 함수형 코드에 가까워진다.
문자열 템플릿
로그나 정보를 출ㅋ력하기 위해 println
을 자주 사용하는데 이를 더욱 편리하게 해주는 코틀린의 기능이다.
1 | fun main(args: Array<String>) { |
여러 스크립트 언어와 비슷하게 코틀린에서도 변수를 문자열 안에 사용할 수 있도록 지원하고 있다. 문자열 리터럴의 필요한 곳에 변수를 넣되 변수 앞에 $
를 추가해야 한다.
코틀린에선
자바와 마찬가지로 한글(글자로 분류할 수 있는 모든 유니코드 문자)을 식별자에 사용할 수 있으므로 변수 이름에 한글이 들어갈 수 있어 변수 이름을 {}
로 감싸는 것을 추천한다.
클래스와 프로퍼티
클래스
코틀린에서는 최신의 언어처럼 간결하게 기술할 수 있는 구문을 제공한다. 특히 값 객체(value object, 코드가 없이 데이터만 저장하는 클래스)
의 경우 더욱 다이나믹 할 수 있다.
1 | // java |
- public 가시성 변경자 삭제 : 코틀린에서는
기본이 public
- 생성자 및 프로퍼티 삭제 : 기본으로 생성
프로퍼티
자바에서는 필드와 접근자를 한대 묶어 프로퍼티(property)라고 부르며, 프로퍼티라는 개념을 활용하는 프레임워크가 많다. 코틀린은 프로퍼티를 언어 기본 기능으로 제공하며 자바의 필드와 접근자 메소드를 완전히 대신한다. 앞에서 살펴본 변수 선언 방법과 마찬가지로 val
로 선언한 프로퍼티는 읽기 전용
이며, var
로 선언한 프로퍼티는 변경 가능
이다.
1 | class Person ( |
코틀린에서는 게터(getter)를 호출하는 대신 프로퍼티를 직접 사용하여 더 간결해졌다.
커스텀 접근자
코틀린에서 제공하는 기본 접근자도 있지만 사용자가 직접 구현이 가능한 커스텀 접근자도 제공하고 있다. 예로 정사각형인지 알려주는 기능이 포함된 Rectangle 클래스는 다음과 같다.
1 | class Rectangle(val height: Int, val width: Int) { |
파라미터가 없는 함수를 정의하는 방식과 커스텀 게터를 정의하는 방식 중 어느 쪽이 더 나은지 궁금할 수 있는데 두 방식 모두 비슷하다. 구현이나 성능상의 차이는 없고 차이가 나는 부분은 그저 가독성
뿐이다.
출처 : Kotlin in Acation