본문 바로가기

IT 정보

[Kotlin] Java 개발자를 위한 코틀린 필수 사항(간결한 코드!)

*이 포스팅은 《다재다능 코틀린 프로그래밍》에서 발췌한 내용입니다.

더 자세한 내용을 보고싶으시면?(클릭)

 

 

단순한 것들은 만들기 쉬워야 하고 복잡한 것들은 비용이 적어야 한다. 컴퓨터의 코어가 몇 개인지 확인하려면 몇 줄의 코드가 필요할까? 아래와 같은 방법은 어떤가?

 

한 줄짜리 코드이며 세미콜론도 없고, 임포트도 없다. Java JDK를 사용해도 관례적으로 입력해야 하는 코드는 훨씬 적다. 이것이 바로 코틀린이다.


코틀린은 작업을 금방 끝내준다. 절차를 강요하지 않는다. 작게 시작해서 크게 키워갈 수 있다. 프로그래밍이란 원래 작은 실험들의 연속이다. 개발자들은 종종 로직이 작동하는지 확인하고 전체 설계와 잘 맞는지 확인하기 위해서 솔루션을 프로토타이핑 한다. 코틀린 스크립트는 코드 낭비 없이 프로토타입을 만들어보는 데 매우 적합하다.


이번 챕터에서 숫자와 문자열 변수 정의하기, 상수 만들기, 타입 명시하기, 계산 결과를 이용해 문자열 표현식 만들기, 멀티라인 문자열 만들기 같은 코틀린의 필수 사항에 대해서 배울 것이다. 스크립트에서는 함수와 메소드의 바디를 만들 때 사용되는 블록을 바로 작성해서 사용할 수 있다. 여기서 배울 코틀린의 필수사항들은 스크립팅, 객체지향적, 함수형 프로그래밍을 할 때 모두 지속적으로 사용될 것이다.


코틀린을 시작하려고 하는 Java 개발자들은 코틀린이 가진 뉘앙스를 배우는 동안에는 Java에서 사용하던 버릇을 좀 잊어야 할 필요가 있다. 이번 포스팅에서는 Java에서 아주 익숙하게 봤더라도 코틀린에 적용하려면 조정해야 하는 부분을 살펴본다. 새로운 안경이나 렌즈를 착용하면 언제나 처음엔 불편하지만 시간이 조금만 지나면 적응된다. 이처럼 처음엔 약간 불편해도 코틀린의 우아한 기능이 적응을 최소화해 여러분을 편안하게 만들어줄 것이다.


우리는 코틀린의 간결함에 대해서 감시하며 시작할 것이다. 코드 한 줄 한 줄은 모두 중요하다. 기본적인 연산자들이 장황하다면 전체 애플리케이션을 간결하게 만들 수 없다. 명령형 스타일이든, 함수형이든, 객체 지향적이든 표현식(expressions)들과 명령문(statements)들이 블록을 만든다. 코틀린은 절차, 노이즈, 산만한 과정을 코드 전체에서 제거한다. 그렇기 때문에 우리가 만든 모든 프로그램은 짧고, 정확하게 표현하고, 관리하기 쉬워진다.


코틀린은 세미콜론, 타입 정의, 클래스 등 다른 언어에서는 필수적인 것들을 몇 가지 선택사항(optional)로 만들었다. 코틀린에서 개발자는 변수를 만들 때 뮤터블(mutable, 변경 가능)인지, 이뮤터블(immutable, 변경 불가능)인지를 결정해야 한다. 문자열 표현식과 멀티라인 스트링을 사용할 때 스트링 탬플릿을 제공해서 고통을 줄여준다. 그리고 뮤터블 변수의 사용을 줄이기 위해서 명령문보다는 표현식을 선호한다.


코드의 가장 기본적인 부분인 한 줄의 명령문 혹은 표현식을 통해서 코틀린의 디자인 철학에 대해서 알아보자. 책을 따라가보면 우리는 코틀린이 어떻게 코드에서 노이즈를 줄이고 변수를 정의하는지 알 수 있고, 경고(Warning)를 이해하고, 타입 추론과 문자열 표현식을 쉽게 사용하고 멀티라인 문자열을 만들 수 있다. 이런 기본적이고 필수적인 코틀린의 콘셉트를 먼저 배워두면 코틀린으로 코드를 작성할 때 영향을 끼칠 것이다.

 

 

  • 타이핑 간단하게! 더 적게!

코틀린으로 애플리케이션을 만들면 더 적게 타이핑(실제로 키보드를 두드리는 행위!) 하게 될 것이다. 왜냐하면 코틀린에서는 많은 것들이 선택적(Optional)이기 때문이다.

 

세미콜론 생략하기

코틀린으로 프로그래밍을 시작하면 지금까지 줄곧 고통받던 오른쪽 새끼손가락은 자유로워질 것이다. 모든 표현식이나 명령문을 세미콜론으로 끝낼 필요가 없다. 세미콜론은 거의 쓰지 않는다. 세미콜론이 필요할 때는 한 줄에 두 개 이상의 표현식이나 명령문을 사용할 때뿐이다.

 

Java나 JavaScript같은 언어에서 코틀린으로 전환하고 있는 중이라면 무의식적으로 세미콜론을 누르고 있을 가능성이 크다. 물론 세미콜론을 사용해도 되지만 코틀린에선 사용하지 않는 게 좋다.

 

 

변수 타입 지정 생략하기

코틀린은 정적 타입 언어이다. 하지만 그게 변수의 타입을 꼭 지정해야 한다는 뜻은 아니다. 정적 타입이란 변수의 타입이 컴파일 시점에 검증되고 정확해져야 한다는 의미다.

 

코틀린은 컨텍스트에 기반한 스마트한 타입 추론 기능을 가지고 있다. 타입을 명시하지 않고 변수를 정의한 후 타입을 확인해보자.

 

::class는 변수에 의해 참조되고 있는 객체의 코틀린 클래스를 확인한다. 그리고 .javaClass는 Java 클래스를 확인한다. 코틀린과 Java의 클래스가 서로 다른 경우는 매우 드물다. 코틀린 컴파일러에 친숙한 클래스들만 차이를 보여줄 것이다.


앞의 예제에서, 코틀린의 타입 추론 기능이 변수에 할당된 값(value)에 기반하여 greet라는 변수의 타입을 String이라고 정의했다. 그리고 이런 세부사항을 출력했다.

 

어떤 개발자들은 타입 추론을 두려워한다. “실행 시간에 확인하는 건가?”, “컴파일 시간에 타입을 체크하면 성능이 안 좋지 않을까?”하는 궁금증을 가진다. 결론부터 말하자면 아니다.


정확히 이야기하자면, 위 코드에서 실행 시간에 참조된 객체의 타입을 나타낸다. 그러면 컴파일 시간에 변수 greet의 타입은 뭘까? 우리는 코드에서 일부러 실수를 만들어서 확인해볼 수 있다.

 

코틀린은 컴파일시점에 greet의 타입이 문자열이라고 판단했다. 그 결과 greet에 정수를 할당하려고 하자 유효하지 않다는 사실을 알 수 있었다. 게다가 val에는 다시 값을 할당할 수 없다. 그래서 이 코드를 스크립트로 실행해도 컴파일 오류가 발생해 실행되지 않았다.

 

코틀린의 타입 추론은 극단적이지 않다. 타입이 명확한 경우에는 타입을 생략할 수 있다. 함수(function)나 메소드(method)를 정의할 때, 리턴타입은 명시하지 않아도 되지만 파라미터 타입은 명시해야 한다. 일반적으로 API의 리턴타입을 명시하는 이유는 라이브러리 내부에서 사용하기 위해서가 아니라 라이브러리를 사용하는 외부의 유저에게 보여주기 위해서다. 《다재다능 코틀린 프로그래밍》책에서는 이런 점을 더 논의해 본다.

 

 

클래스와 함수 생략하기

Java같은 언어와는 다르게, 코틀린은 명령문이나 표현식이 메소드에 속할 필요가 없고, 메소드는 클래스에 속할 필요가 없다. 최소한 우리가 만드는 소스코드 안에서는 말이다. 코드가 컴파일되거나, 스크립트로 실행될 때 코틀린은 JVM에서 실행하기 위해 필수적으로 필요한 랩퍼(wrapper) 클래스와 메소드를 생성한다.

 

작은 코드를 작성할 때 파일 안에 코드를 바로 작성하면 스크립트로 동작된다. 클래스와 메소드를 만들기 위한 관례적인 코드가 필요 없다. 물론 큰 애플리케이션을 작업할 때는 클래스와 메소드를 만들어야 할 것이다. 간단한 코드는 간단하게 만들고, 복잡한 코드는 더 정밀하고 구조적이어야 한다.

 

 

try-catch는 선택사항이다

Java 컴파일러를 사용할 땐 명시적 예외(Checked Exception)를 확실하게 처리(catch)하거나 전달(throw)해야 한다. 명시적 예외가 좋은지 나쁜지에 대한 논쟁은 영원히 결론이 나지 않을 것이다. 명시적 예외를 좋아하는 개발자가 있는가 하면 싫어하는 개발자들이 있다. 우리는 그런 논쟁을 할 필요가 없다. 코틀린이 제공해주는 대안은 무엇인지 살펴보도록 하자.
코틀린은 checked이든 unchecked든 상관없이 어떠한 예외도 처리하도록 강제하지 않는다. 만약에 try-catch문이 없는 함수를 호출했을 때 예외가 발생하면 자동으로 해당 함수를 호출한 함수 또는 호출한 코드로 전달된다. 호출한 코드나 함수에서 예외를 핸들링하지 않는다면 프로그램은 종료된다.


예를 들어보자. Java의 Thread 클래스에 속한 sleep() 메소드는 명시적 예외를 전달한다. 그리고 컴파일러는 해당 예외를 반드시 처리하도록 강제한다. 그 결과 sleep() 메소드를 부르는 모든 호출을 try문으로 감싸야 하고, sleep() 메소드가 전달할 수 있는 InterruptedException을 어떻게 처리해야 할지 고민하느라 시간을 써야 한다. 코틀린을 사용하면 그럴 필요가 없다.

 

 

위 코드엔 try-catch문이 없다. 그러나 실행시켜 보면 첫 줄이 출력되고 1초가 지난 후에 두 번째 줄이 출력된다.


예외처리를 위해서는 방어적 프로그래밍*을 하는 게 좋다. 코틀린은 try-catch문을 강요하지 않는다. 그렇기 때문에 Java처럼 컴파일러의 체크를 통과하기 위해 불필요한 빈 catch 블록을 만들 필요가 없다. 개발자가 직접 다루지 않은 예외는 자동으로 호출한 코드로 전파된다는 것을 기억하도록 하자.


코틀린 컴파일러가 요구사항을 줄여 어떻게 유연성을 제공하는지 보았다. 동시에 코틀린 컴파일러는 코드를 안전하게 만들기 위해서 코드 안에 잠재된 오류도 확인한다. 다음 포스팅에서!!

 

 

《다재다능 코틀린 프로그래밍》

 

예스24 / 교보문고 / 알라딘 / 인터파크

 

(공감)은 많은 힘이 됩니다 :)

반응형