본문 바로가기

코틀린

(34)
코틀린(Kotlin) - 런타임에서의 제네릭의 동작 알고 계시겠지만 JVM의 제네릭은 보통 타입 소거(type erasure)를 사용해서 구현됩니다. 타입 소거(type erasure) - 원소 타입을 컴파일 타임에만 검사하고 런타임에는 해당 타입 정보를 알 수 없는 것입니다. - 즉, 컴파일 타임에만 타입에 대한 제약 조건을 적용하고, 런타임에는 타입에 대한 정보를 제거한다는 뜻입니다. 이 말은 런타임에서 제네릭 클래스의 인스턴스에 타입 파라미터 정보가 들어있지 않다는 뜻입니다. 이번에는 코틀린 타입 소거가 어떤 영향을 끼치는지 살펴보고 함수를 inline으로 선언함으로써 이런 제약을 어떻게 우회할 수 있는지 확인하도록 하겠습니다. 먼저 결론부터 말씀드리자면, 함수를 inline으로 만들면 타입 파라미터가 소거되지 않게 할 수 있습니다. 런타임에서의 제..
코틀린(Kotlin) - 제네릭 타입 파라미터 자바와 동일하게 제네릭을 사용하면 타입 파라미터를 받는 타입을 정의할 수가 있습니다. 문자열을 담는 리스트를 표현할 때 자바와 마찬가지로 List을 쓰는 것과 같이 타입 파라미터를 사용하면 훨씬 더 명확하게 타입 추론을 할 수 있게 됩니다. 예를 들어 리스트를 만들 때, 아래와 같이 변수의 타입을 지정해도 되고 val list: MutableList = mutableListOf() 변수를 만드는 함수의 타입 파라미터를 지정해도 됩니다. val list = mutableListOf() 제네릭 함수와 프로퍼티 예를들어, 리스트를 다루는 코드를 짜다보면 어떤 특정 타입을 지정하는 리스트뿐 아니라 모든 타입을 다룰 수 있는 리스트 관련 메소드가 필요한 경우가 생길 수 있습니다. 이럴 때 범용적으로 사용할 수 있..
코틀린(Kotlin) - 고차 함수 안에서 흐름 제어 루프(Loop) 같은 명령형 코드를 람다로 쓰기 시작하게 되면 반드시 return 문제에 부딪히게 되실 겁니다. 일반적으로 흔히 알고 있는 루프 안에서 return을 하게 될 때와 달리, object.forEach() { } 와 같이 람다 안에서의 return을 하게 되면 어떻게 되는지 살펴보도록 하겠습니다. 람다 안의 return문 : 람다를 둘러싼 함수로부터 반환 /* 일반 루프 안에서 return 사용 예제 */ fun example() { val list = listOf(1, 2, 3, 4, 5) for (element in list) { if (3 == element) { println("return!") return } println(element) } } >>> example() 1 2 re..
코틀린(Kotlin) - inline 함수 : 람다의 부가 비용 없애기 람다의 경우 컴파일 단계에서 파라미터 개수에 따라 FunctionN 형태의 인터페이스로 변환이 됩니다. 예를 들어 아래와 같이 파라미터가 두 개인 람다 식은 Function2 의 인터페이스로 변환이 되는 것을 알 수가 있습니다. fun calculator(x: Int, y: Int, operation: (Int, Int) -> Int) { operation(x, y) } /* 컴파일 시, FunctionN 형태의 인터페이스 구현 객체로 변환 */ public final void calculator(int x, int y, @NotNull Function2 operation) { Intrinsics.checkNotNullParameter(operation, "operation"); operation.inv..
코틀린(Kotlin) - 고차 함수 정의 고차 함수 고차 함수는 다른 함수를 파라미터로 받거나 함수를 반환하는 함수입니다. 즉, 람다나 함수 참조를 파라미터로 받거나 람다나 함수 참조를 반환하는 함수입니다. 예를 들면 filter 함수는 Boolean값을 반환하는 람다식을 파라미터로 받고 있기 때문에 고차 함수입니다. list.filter { it > 0 } /* filter 함수 Body */ public inline fun Iterable.filter(predicate: (T) -> Boolean): List { return filterTo(ArrayList(), predicate) } 이 외에도 map, with 등의 여러 고차 함수들을 이미 알고 계실 텐데요, 이제는 그런 고차 함수를 정의하는 방법에 대해 살펴보도록 하겠습니다. 함수 타..
코틀린(Kotlin) - 프로퍼티 접근자 로직 재사용 : 위임 프로퍼티 코틀린이 제공하는 convention에 의존하는 특성 중 가장 독특하면서 강력한 기능인 위임 프로퍼티(delegated property)에 대해서 살펴보도록 하겠습니다. "위임"은 자신이 직접 작업을 수행하지 않고 다른 객체에게 그 작업을 처리하도록 맡기는 디자인 패턴을 말합니다. 즉, 프로퍼티 필드에 접근하는 getter/setter 메소드를 가지는 다른 객체를 만들어서 그 객체에 프로퍼티 필드 접근 로직을 위임하는 것입니다. 이때 이러한 작업을 위임받아서 처리하는 중간자 역할인 서포트 객체를 위임 객체(delegate) 라고 하며, 위임하도록 선언한 객체는 위임 객체의 멤버를 참조없이 호출이 가능하고, getter/setter 로직을 다른 객체 간에 공통으로 재사용해야 하는 경우 매우 유용합니다. 왜..
코틀린(Kotlin) - 구조 분해 선언과 component 함수 데이터 클래스의 특성 중 convention 원리와 관련된 특성인 구조 분해 선언(destructuring declaration)에 대해 살펴보도록 하겠습니다. 데이터 클래스에 대한 기본적인 내용은 아래 포스팅을 참고하시면 됩니다. ^^ 2020.03.03 - [코틀린] - 코틀린(Kotlin) - 데이터 클래스와 클래스 위임(by) 코틀린(Kotlin) - 데이터 클래스와 클래스 위임(by) 자바와 마찬가지로 코틀린 클래스도 toString, equals, hashCode 등을 오버라이드 할 수 있고, 코틀린은 이런 메소드 구현을 자동으로 생성해줄 수 있습니다. 데이터 클래스 어떤 클래스에 대해 toString, 0391kjy.tistory.com 디스트럭쳐링(Destructuring) 구조 분해를 사..
코틀린(Kotlin) - 산술 연산자 오버로딩 코틀린에서는 특정 연산자의 역할을 함수로 정의할 수 있습니다. 이를 Convention(관례)이라고 합니다. 가장 기본적인 예로는 산술 연산자가 있습니다. 자바에서는 원시 타입(primitive)에 대해서만 산술 연산자를 사용할 수 있고, 추가로 String에 대해 "+" 연산자를 사용할 수 있습니다. 그러나 다른 클래스에서도 이러한 산술 연산자가 유용한 경우가 있기 마련입니다. 지금부터, 어떻게 클래스에 대한 일반 산술 연산자를 정의할 수 있는지에 대해 살펴보도록 하겠습니다. 이항 산술 연산 오버로딩 코틀린에서는 +, - 같은 산술 연산자를 오버로딩해서 사용할 수 있습니다. 객체끼리 더하거나 뺄 때, 원하는 동작을 함수 안에 구현하면 연산자를 통해 이를 표현할 수 있습니다. /* plus 연산자 구현하..