PPAK

[kotlin] 코틀린 1일차의 뭣도 모르고 쓰는 소감 본문

jvm/kotlin

[kotlin] 코틀린 1일차의 뭣도 모르고 쓰는 소감

PPakSang 2022. 9. 12. 18:29

첫 스프링 프로젝트의 MVP 작업이 끝나고 클라이언트 개발팀의 QA 를 하고 있는 상황에서 중간 중간 시간이 길게 비는 듯한 느낌이 들어 미루고 또 미루었던 코틀린에 대해서 학습을 해볼까하고 작일 자정부터 입문을 했습니다.

 

사실 학습한지 하루 밖에 안된 상황에서 이렇게 포스팅을 쓰는 것이 다소 부끄럽게 느껴지긴 하지만,  Java 언어와 매우 유사한 형태의 문법을 가지고 있어서 생각보다 빠르게 많은 정보가 들어와 첫 사용 당시의 느낌과 함께 학습 내용을 정리해보고자 합니다.

 

(본 포스팅의 내용이 다소 부정확할 수 있으며 추후 학습을 이어나가면서 수정할 예정입니다. 현재는 소감문 정도로 봐주시면 감사하겠습니다.)

 

코틀린 자체가 완전히 새로운 패러다임은 아니지만 JVM 에서 동작하던 기존의 Java 언어를 개선하여 더 간결하고 쉽게 사용할 수 있도록 만든 하나의 프로그래밍 언어입니다.

 

Java 와 명확히 구분되는 특징들이 많긴하지만 실제로 사용해보면 Java 의 개선된 언어가 맞구나 하는 느낌이 들었습니다.

 

어떤 것이??

 

처음에 가장 눈에 띄었던 특징은 코틀린 기본 변수 타입은 Null 참조를 허용하지않고 Nullable 한 타입을 따로 명시를 해주어야 한다는 것입니다.

 

예시로 아래 두 가지 코드 중 위의 코드는 컴파일 시점에 오류를 발생시킵니다. 반대로 아래 변수 타입에 ? 이 붙은 변수의 경우에는 null 참조가 가능하게 됩니다.

 

스프링을 통해 개발을 할 때에도 null 케이스를 핸들링하기 위해서 Optional.ofNullable(instance) 과 같이 Optional 타입을 생성하여 처리를 해주었는데, 코틀린에서는 아래와 같은 null 참조를 컴파일러 차원에서 체크해주기 때문에 해당 기능이 있다는 사실만으로 무언가 마음이 편해졌습니다.

val notNull: Int = null
val nullable: Int? = null

 

타입 추론도 정말 좋았습니다. 물론 자바에서도 var 를 제공하긴 하지만 코틀린은 이 var 키워드를 이용한 더 많은 기능을 제공할 뿐더러 자바 컨텍스트에서 var 를 억지로 끼워넣을 필요는 없다고 생각합니다.

 

사실 저의 경우에는 여전히 명시적인 형태의 변수가 더 좋긴 하지만, 충분히 생략할 수 있는 부분(참조 변수와 생성된 객체의 타입이 같은 경우, 같은 스코프(인접한 코드라인) 내에서 선언하고 사용하는 변수 등등) 에서는 유연하게 코드를 작성할 수 있게 되었다는 생각이 들었습니다.

 

한 가지 코드를 작성하다 타입 추론 부에서 initializing 을 강제하기에 왜 그런지 찾아봤더니 타입 추론 자체는 컴파일 시점에 이루어지는 작업이기 때문에 컴파일러가 예측 불가능한 변수에 대해서는 에러를 발생시킨다고 합니다. 컴파일 시점에 이루어지니 애플리케이션 성능에는 영향이 없다는 사실 또한 알 수 있었습니다.

 

var 와 val 의 차이는 자바의 일반 변수와 final 의 차이(variable, value)  그런데 이제 다양한 기능을 곁들인...  라고 이해하면 될 것 같습니다.

 

위에서 언급한 var 키워드를 통해서 코틀린이 제공하는 정말 유용한 기능이라고 생각이 든 부분 중 하나는 아래와 같은 class 의 primary 생성자에 var 와 val 키워드와 함께 타입을 명시해주면 컴파일 타임에 getter/setter 가 자동으로 추가됩니다. 즉 class property 를 자동 으로 생성해줍니다.

class Sample(var name: String, val birthDay: Date)

 

primary construtor, secondary construtor 역시 굉장히 생소했는데 위와 같이 컴파일 타임에 수행할 수 있는 기능을 확장하고 조금 더 직관적인 클래스 프로퍼티 선언을 위해서 존재하는 것 같다고 현재는 느껴집니다.

 

primary construtor 는 아래와 같이 class header 라고 하는 부분에 선언하고 따로 접근 제어자가 필요하지 않으면 생략 가능합니다. primary constructor 는 클래스의 기본 생성자이기도 한데 아래 class body 부분에 생성한 secondary constructor 는 항상 이 primary constructor 에게  아래와 같이 this(...) 를 통해 생성자 호출을 위임해야합니다.

 

init(), apply/also, run/let 등 코틀린만의 클래스 예약 메소드들이 많은데 이 부분은 조금 더 학습을 해보고 정리해보도록 하겠습니다.

 

코틀린은 property 는 var, val 키워드를 통해서만 선언이 가능하고, 기본적으로 모든 값이 초기화된 상태여야 합니다. 하지만 lateinit 같은 초기화를 뒤로 미루는 예약어를 제공해주기도 합니다. (매커니즘이 JPA 의 lazyLoading 과 상당히 흡사하다고 느낀것이 참조 전에는 에러를 발생시키지 않지만 참조 당시 해당 값이 초기화되어있지 않다면 그제서야 에러를 발생시킵니다.)

class Person(var name: String) {
    private val space = "Korea"
    constructor(name: String) : this(name)
}

패키지, 클래스 스코프 관리도 새로웠습니다. 코틀린은 기본적으로 접근 제어자를 명시하지 않으면 public 으로 설정을 합니다. 또한 public, internal, private 접근 제한자를 통해서 패키지 스코프를 관리할 수 있고. 특히 internal 은 같은 모듈내에서의 접근을 허용한다는 사실을 통해 모듈의 존재를 다시금 상기했습니다.

 

그리고 forloop... 좋습니다.......

for (i in 1..10 step 3)
for (j in 10 downTo 1)

함수형 프로그래밍 지원 또한 자바와 비교해서 조금 더 깔끔해진 것 같습니다. 아직까지 함수형 프로그래밍에 대한 이해도가 낮아 다양한 활용은 못해봤지만 자바에서는 Consumer, Supplier, Function, Predicate, Operator 등등 익명 함수를 참조하는 클래스를 별도로 명시해야하는 것과는 달리 마치 익명 함수의 형태를 타입으로 줄 수 있어 굉장히 편리했습니다.

 

아래는 예시 코드입니다. 함수의 인자가 단 하나일 때 이를 생략하고 it 이라는 예약어를 사용할 수 있다는 점과 위에서 언급한 익명함수의 형태를 타입으로 지정가능한 것, return 예약어 없이 마지막 줄의 값을 암시적 리턴타입으로 처리하는 등의 새롭지만 편리한 기능들이 있는 것을 확인할 수 있었습니다.

var findPerson:(Person) -> Boolean = {
    it.name == "Peter"
}

fun main() {
    val person = Person("Peter")
    findPerson(person)
}

 

 

 

하루동안 언어를 살펴보는 수준에 못미쳤지만 짧은 시간동안 여러가지 것들을 상기하고, 코틀린이라는 언어에 더더욱 관심을 가지게 된 계기가 되었던 것 같습니다. 사실 타입 추론의 경우 다른 언어에서는(js 류 언어, swift 등등) 흔하게 볼 수 있는 기능인데 이번 기회를 통해 제가 한동안 한 가지 언어에만 치중하고 있었던 것은 아닌가 하는 생각도 들었습니다. 그래서 이번 코틀린 학습을 병행하면서 코프링, 안드로이드 등등도 경험해 봐야겠습니다..!!

Comments