Kotlin
Kotlin 확장 함수 활용하기

Kotlin 확장 함수 활용하기

Kotlin 언어를 사용하다보면 이런 구문이 자주 보이게 될겁니다. T.apply {}, T.run {} 등 Java에는 없지만 Kotlin에 존재하는 확장함수라는 것을 직접 만들어보도록 하겠습니다. 확장함수(Extension Function) Java에서 기본으로 제공되는 클래스들에 함수를 추가하려면 새로운 클래스를 만들거나 static함수를 만들어 사용해야만하는 불편함이 있었습니다. 간단한 예를 들기위해 boolean과 int간의 형변환 예제를 만들어 보겠습니다. 삼항연산자로 짧은 코드를 만들었지만, 한눈에 의미를 파악하기 어렵고, 이런 코드가 반복되다보면 그렇게 보기좋은 코드가 되지 못합니다. 그래서 별도의 사용자 클래스내의 static타입의 함수를 만들어 사용하기도 했습니다. (어디까지나 설명을 위해 만든 예제이고, 실제로 이런식으로 bool과 int간의 형변환을 자주 사용하진 않습니다.) 하지만 Kotlin에서는 확장함수를 통해 Int와 Boolean 클래스에 함수를 만들어줘 클래스를 만드는 번거로움이 없이 편하게 함수를 추가할 수 있습니다. Int와 Boolean클래스에 확장함수를 만들어 주어 기존 클래스에 있는 것처럼 사용할 수 있습니다. 참고로 이렇게 확장함수를 넣어주게되면 100.toBoolean(), true.toInt() 이런식의 코드 또한 가능합니다. 람다식(Lambda Expression) Kotlin의 람다식은 변수처럼 활용이 가능합니다. 특정 함수내에서만 존재하는 함수를 만들거나, 상황에 따라 함수의 내용이 수정되어야 할때 아주 유용한 방법입니다. 람다식을 매개변수로하는 함수 하나를 만들어 보겠습니다. Int 클래스에 returnMe라는 함수를 하나 만들었습니다. 이 함수는 약간 복잡해 보이지만 천천히 보시면 이해할 수 있습니다. 먼저 매개변수인 some을 보겠습니다. () -> String으로 String을 리턴하는 람다식입니다. 하지만 Int.()으로 시작하는 걸보면 이 람다식은 Int의 확장 함수로 사용됩니다. 따라서 returnMe라는 함수 내에서는 Int클래스에는 some이라는 함수를 사용할 수 있습니다. 함수의 내용을 보시면 = this.some()이 오는데 현재 returnMe라는 함수는 Int클래스의 확장 함수이므로 this는 Int형 객체가 됩니다. 그러니 some()이라는 확장 함수가 사용할 수 있는 것이죠. 그 리턴값은 String형으로 returnMe 함수의 리턴값으로 다시 넘겨지게됩니다. 마지막으로 사용하는 4~5라인을 보시면 아시겠지만, Kotlin의 함수에서 마지막 매개변수가 람다식이면 이는 ()에서 생략이 가능해집니다. 최종적으로는 T.apply {}와 같은 형태가 되는것이죠. Kotlin의 확장 함수뿐만 아니라 람다식과 함께 쓰인다면 좀더 좋은 시너지 효과를 낼 수 있습니다. 물론 예제처럼 굳이 사용할 필요가 없는 곳에서 사용해 남용하게되면 이는 좋지 못한 코드가 되겠지만 그 부분은 이 글을 읽으시는 분이 직접 판단하셔야 할 부분입니다. 오타, 오류 등이 있다면 댓글이나 이메일을 통해 알려주시면 감사하겠습니다. :D

Kotlin 표준 함수 마스터하기

Kotlin 표준 함수 마스터하기

※ 본 게시글은 해외 포스팅을 번역한 글입니다. 원본 : Elye’s Medium 코틀린에는 어떻게 사용해야할지 확실하지 않을 정도로 유사한 표준함수가 있습니다. 이들의 차이점과 어떤걸 선택해야하는지 명확하게 구별하는 쉬운방법을 소개하겠습니다. 스코프 함수 저는 run, with, T.run, T.let, T.also 그리고 T.apply에 초점을 맞췄습니다. 저는 호출 함수의 내부 스코프를 제공하는 것처럼 주요기능을 볼때 스코프 함수라 부릅니다. 스코프 함수인 run함수를 쉬운방법으로 설명해드리겠습니다. test함수의 내부를 보면, mood를 출력전에 I am happy라고 재정의한 격리된 스코프가 있고, 이는 완전히 격리된 run 스코프입니다. 이 스코프 함수 자체로는 매우 유용해 보이진 않습니다. 하지만 스코프보다 좋은 것이있습니다. 스코프의 마지막 객체를 반환하는 것입니다. 아래의 적절한 예제로, 두개의 뷰에 두번 사용하지 않고 show()를 사용할 수 있습니다. 스코프 함수의 3가지 속성 스코프 함수들을 좀더 흥미롭게 만들려면, 3가지 속성을 분류하세요. 저는 이런 속성들을 각각 구분하기 위해 사용할 것입니다. 1. 일반 vs 확장 함수 with와 T.run를 보면, 두 함수 모두 실제로 꽤 비슷합니다. 아래의 예제도 같습니다. 그러나, 둘의 차이는 with는 일반 함수고, T.run은 확장 함수입니다. 그럼 질문, 각각의 이점은 무엇일까요? webview.settings가 null이 될 수 있다고 생각해보면, 아래와 같이 보일겁니다. 이경우, 확실히 T.run 확장 함수가 사용하기 전에 null 체크를 적용할 수 있어 더 낫습니다. 2. 매개변수 this vs it T.run과 T.let을 본다면, 두 함수 모두 매개 변수를 받는 것을 제외하고 닮았습니다. 아래의 예제는 두 함수 모두 같은 로직입니다. T.run함수의 기호를 확인해보면, T.run은 block: T.()으로 보이는 확장함수로 만들어진 것을 알 수 있습니다. 그런 까닭에 스코프 내의 모든 곳에서 T는 this로 부를 수 있습니다. 프로그래밍에서, this는 대부분에서 생략될 수 있습니다. 그러므로 위의 예제에서, println에서 ${this.length}대신, length로 사용할 수 있습니다. 저는 이를 this를 매개변수로 보낸다고 부릅니다. 그러나 T.let함수의 기호에서, T.let은 자기자신을 block: (T)인 함수로 보낸다는걸 알 수 있습니다. 그런 까닭에 이는 람다 매개변수로 보내는 것 같습니다. 스코프 내에서는 it으로 불릴 수 있습니다. 따라서 저는 it을 매개변수로 보낸다 부릅니다. 위에서는, T.run이 T.let보다 함축적으로 더 유용한 것으로 보입니다만, T.let 함수에는 아래와 같이 눈에 띄지않는 장점들이 있습니다. T.let은 넘겨진 함수/멤버 변수인지, 외부 클래스의 함수/멤버 변수인지 명확하게 구분됩니다. this가 생략되지 않는 상황에서, 예를들어 함수의 파라미터로 넘겨졌을 때, it은 this보다 짧게 쓸 수 있고, 보다 깔끔합니다. T.let은 변수를 보다 나은 이름으로 바꿀 수 있습니다. 즉, it을 다른 이름으로 변환할 수 있습니다. 3. this vs 다른 타입 반환 이제, T.let과 T.also를 살펴보면, 함수 내부의 스코프를 본다면, 둘다 똑같습니다. 그러나 그것들의 반환값이 파악하기 힘들게 다릅니다. T.let은 다른 타입의 값을 반환하지만, T.also는 T 자기 자신 즉, this를 반환합니다. 둘다 체이닝 함수(chaining function)에서는 유용합니다. T.let은 조작을 진화시켜주고, T.also는 같은 변수 즉, this를 사용하게 해줍니다. 아래의 간단한 실제 예제가 있습니다. 위의 T.also는 의미 없어 보이며, 쉽게 함수의 한개의 블럭으로 합칠 수 있습니다. 잘 생각해보면, 약간의 장점이 있습니다. 같은 객체에서 작업을 깔끔하게 분리할 수 있습니다. 즉, 함수의 영역을 작게 만들수 있습니다. 사용전에 체인 빌드 기능을 만드는 것에서 자기자신을 교묘히 다루는 것을 매우 강력해질 수 있습니다. 체인을 합칠때 즉, 자기자신을 진화하고, 유지할때 아래와 같이 매우 강력해질 겁니다. 모든 속성 보기 3개의 속성을 보면, 함수의 행동을 거의 알 수 있습니다. T.apply 위에서 말한것과 다르게, 함수를 설명해 봅시다. 아래에 T.apply의 3가지 속성이 있습니다. 확장 함수 입니다. this를 매개변수로 보냅니다. this(즉, 자기자신)을 반환합니다. 여기서 부터 사용해보면, 한가지로 아래와같이 상상할 수 있습니다. 또는 체인되지 않은 객체를 체인할 수 있게 만들 수 있습니다. 함수 선택 명백히 이제 3개의 속성으로, 함수들을 카테고리로 나눌 수 있습니다. 그리고 이것으로, 우리가 필요할때 어떤 함수를 사용해야 하는지 결정을 도와줄 수 있는 아래와 같은 결정 트리 형식을 만들 수 있습니다. 오역, 의역 등 문제점이 있을 수 있습니다. 이러한 경우 댓글로 알려주시기 바랍니다. 처음 번역해 올려보는거라 이미지가 번역이 안된점이 아쉽지만, 이는 후에 포스트를 업데이트 하겠습니다.

Kotlin 콘솔에서 입력받는 3가지 방법

Kotlin 콘솔에서 입력받는 3가지 방법

Kotlin이란 언어는 Java의 클래스, 메소드가 대부분 사용이 가능한 언어입니다. 그런 Kotlin언어의 콘솔 프로그램에서 입력을 받는 방법 3가지를 소개하겠습니다. 1. readLine Kotlin 기본 함수중에는 readLine()이라는 함수가 있습니다. 이 함수는 콘솔창에서 입력이되면, 줄개행(엔터)를 기준으로 한줄씩 읽게되는 함수입니다. 이 함수의 리턴 타입은 String?이며, ?가 붙은 Nullable 타입입니다. 즉, 입력을 받을때 Null이 올 수 있는 함수입니다. 입력 12345abc 출력 12345abc 2번줄: !!을 붙여 Not Null타입으로 변환해줬습니다. 3번줄: readLine()!!을 통해 읽어들인 한줄을 그대로 println을 통해 출력합니다. 2. Scanner Java에서 사용하던 Scanner라는 클래스입니다. Kotlin에서는 Java의 클래스와 메소드를 전부 사용가능합니다. 입력 1234 출력 1234 1번줄: Java의 Scanner클래스를 사용하기 위해 import키워드를 사용해 가져왔습니다. 4번줄: Scanner객체를 생성합니다. System.`in`은 Kotlin의 in이라는 키워드가 겹쳐 `in`으로 사용합니다. 5번줄: 만들어진 객체를 이용해 정수를 읽어들입니다. 6번줄: 읽어들인 정수를 출력합니다. 3. BufferedReader 이 또한 Java에서 사용하던 클래스입니다. Scanner를 이용하는 것보다 빠르니 알고리즘 풀이할때 많이 쓰이고, 기타 파일 입출력, 리눅스 또는 OSX에서 파이프 실행등에서 많이 쓰입니다. 입력 가나다라마바사 1234567 abcdEFGH 출력 가나다라마바사 1234567 abcdEFGH 1번줄: BufferedReader 클래스를 가져옵니다. 4번줄: 객체를 생성합니다. 생성자의 매개변수는 Reader클래스 객체가 필요하므로 System.`in`.reader()를 사용합니다. 6번줄: 4번줄에서 생성한 객체를 이용해 Kotlin확장 함수인 forEachLine이라는 람다식 함수를 사용합니다. 이 함수로 입력받은 버퍼의 각 줄별로 람다식을 실행하게됩니다. 따라서 각줄의 내용을 println을 통해 출력하는 내용입니다. ※ Kotlin의 람다식에서 매개변수가 1개이고, 별다른 별칭을 지정안해주면 매개변수의 이름은 기본적으로 it으로 설정됩니다. Java클래스가 사용이 가능하다는 점으로 위에 설명한 3가지 방법 말고 다른 방법의 키입력, 버퍼읽기등이 있습니다. 제가 아직 모르는 내용의 함수도 있고, 설명이 미흡하기도 합니다. 언제든지 댓글로 추가적인 내용이나 오타, 수정 등의 지적을 해주시면 감사합니다.

[Kotlin] HelloWorld

[Kotlin] HelloWorld

Kotlin이란 언어는 IntelliJ IDEA라는 개발환경을 만든 Jetbrain에서 고안한 언어이고, 그 종류는 JVM / JS / Native 세종류로 나눠집니다. Native는 네이티브 실행파일(Windows, Linux, OSX 실행파일, .so라이브러리 등)이며, JS는 JavaScript로, JVM은 Java언어로 컴파일됩니다. Kotlin JVM JVM은 Java Virtual Machine의 약자이며, Java언어를 사용할때 배울수 있는 가상머신의 일종입니다. (여기서는 간단한 과정만 설명하겠습니다.) Java라는 언어는 어떤 운영체제, CPU든 종류에 따지지 않고 사용할 수 있는 프로그래밍 언어입니다. 하지만 이런 Java를 있게한건 JVM이고, 이 JVM은 각 운영체제, CPU별로 배포가 되어있는 상태입니다. 그런 JVM위에서 돌아가는 것이 Java이고, 이를 통해 운영체제, CPU와 자유로운 프로그래밍이 가능해집니다. Kotlin JVM은 이 JVM에서 실행할 수 있는 바이트코드인 .class파일로 컴파일 하는 과정이있고 중간에 Java언어로 한번 변환이 됩니다. 전체적인 과정은 .kt(Kotlin) -> .java(Java) -> .class(바이트코드) 순으로 컴파일됩니다. (JVM종류에 따라서 .class가 아닌 다른 파일로 추가변환과정이 있을 수 있습니다.) 제가 이 내용을 넣은 이유가 Kotlin Android를 하게되면 Kotlin 기본제공 함수들이나 AndroidX함수들을 남발하게되는데 실제 .java로 컴파일되는 과정을 보게되면, Java언어로 무겁게 구현된 메소드를 사용한 Kotlin함수가 존재하며, 이를 과도하게 사용해 실제 앱의 성능을 떨어트리는 결과를 초래할 수 있습니다. 따라서 성능에 문제가 생기거나하는 이유가 발생할 수 있으니, 웬만해서는 Java언어도 참고하시는게 좋습니다. 제가 할 강좌는 Kotlin JVM이며, 이는 Kotlin Android에서도 사용가능한 함수 / 메소드를 다뤄볼 예정입니다. Hello World! 이번 강좌는 언제나 어떤 언어든간에 처음시작하게되는 Hello World출력 프로그램입니다. 실제 개발환경은 Intellij IDEA를 추천드리며, 이곳을 통해 무료인 Community버전을 다운받으실 수 있습니다. Hello World! 1번줄: Kotlin의 메인함수입니다. Kotlin으로 만든 프로그램은 모두 여기 main함수에서 시작됩니다. 2번줄: println이라는 Kotlin기본 함수를 통해 출력합니다. 해당 함수는 Java의 System.out.println 메소드를 실행하게 되어있습니다. Wikipedia - JVM Wikipedia - 바이트코드