분류 전체보기

    [Kotlin] 제네릭 사용 시 Cannot check for instance of erased type: T 오류 해결 방법 : inline과 reified를 사용한 문제 해결

    Cannot check for instance of erased type: T 오류는 왜 발생할까? JVM은 제네릭 타입을 실행 시점에 지원하지 않기 때문에, 자바의 제네릭과 마찬가지로 코틀린의 제네릭 또한 컴파일 타입에 타입 지워짐(Type Erasure)이 발생한다. 이 때문에 제네릭을 사용하는 일반 함수에서는 함수 본문에서 제네릭 타입을 이용해 연산을 할 수 없다. 예를 들어 다음과 isType 함수를 살펴 보자. fun isType(value: Any): Boolean { return value is T } 이 함수는 겉보기에는 문제가 없어 보인다. 하지만, T라는 타입은 컴파일 시점에 지워지고, 실행 시점에는 T가 무슨 타입인지 알 수 없기 때문에 다음과 같은 오류가 발생한다. Cannot ch..

    [Kotlin] inline fun 함수를 사용한 고차 함수 최적화

    함수의 매개 변수로 람다식을 받을 경우의 문제 일반적으로 함수를 호출하면 해당 함수가 서브루틴으로써 실행된다. 반면 inline fun으로 선언된 함수를 호출하면, 함수 호출을 실행하는 것이 아니라 해당 함수가 호출된 위치에 함수 내부의 코드가 삽입돼 실행된다. 예를 들어 다음과 같은 코드가 있다고 해보자. fun main(args: Array) { printWorldAfterFunction { println("Hello") } } fun printWorldAfterFunction(function: () -> Unit) { function() println("World") } 이 코드에서 printlnWorldAfterFunction 함수를 () -> Unit 타입의 람다식과 함께 실행하면, () -> ..

    [Kotlin] operator fun 을 통한 연산자 오버로딩 한번에 정리하기

    operator fun이란 코틀린은 특정한 부호의 연산을 함수로 정의할 수 있는 연산자 오버로딩 기능을 제공한다. 예를 들어 plus 라는 함수를 operator fun으로 선언하면 + 연산과 같은 효과를 낸다. 예를 들어 다음 Vector 클래스를 살펴보자. data class Vector(val x: Float, val y: Float) { operator fun plus(vector: Vector): Vector { return Vector(this.x + vector.x, this.y + vector.y) } } 이 Vector 클래스는 operator fun plus을 선언하고 있으며, 이 함수는 두 Vector를 더할 때 x 값은 x 값끼리, y 값은 y 값끼리 더해 Vector 객체의 x 값..

    [Kotlin] MutableMap 사용 시 java.util.ConcurrentModificationException 문제 해결법

    문제 원인 Kotlin에서 mutableMapOf 함수를 통해 생성되는 MutableMap 객체는 내부적으로 Java의 LinkedHashMap을 사용한다. 이 LinkedHashMap은 내부에서 LinkedHashIterator이란 것을 사용하는데, 이 객체는 원소를 순환할 때 LinkedHashMap이 실제로 조작된 횟수(modCount)와 순환이 시작될 때 확인된 조작된 횟수(expectedModCount)의 값을 비교해 만약 두 값이 일치하지 않으면 ConcurrentModificationException을 발생시킨다. abstract class LinkedHashIterator { ... int expectedModCount; ... final LinkedHashMap.Entry nextNode..

    [Kotlin] UByte, UShort, UInt, ULong 사용해 부호 없는(Unsigned) 정수 다루기

    코틀린의 양의 정수 타입 일반적인 다른 언어들과 같이 코틀린에서도 부호 없는 정수(0 보다 크거나 같은 정수)형 데이터 타입을 다루기 위한 다양한 타입들이 코틀린 1.5버전부터 지원되기 시작했다. 글의 제목이 있는 UByte, UShort, UInt, ULong이 그 타입들이다. 변수를 각 타입으로 만드는 방법은 어렵지 않다. 우리가 Float을 선언할 때 접미어로 f를 붙이는 것처럼 접미어로 U를 붙여주면 된다. fun main() { val uByte: UByte = 100U // U를 붙여주어야 한다. val uShort: UShort = 10_000U // U를 붙여주어야 한다. val uInt: UInt = 1_000_000U // U를 붙여주어야 한다. val uLong: ULong = 10..