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
문제 원인 Kotlin에서 mutableMapOf 함수를 통해 생성되는 MutableMap 객체는 내부적으로 Java의 LinkedHashMap을 사용한다. 이 LinkedHashMap은 내부에서 LinkedHashIterator이란 것을 사용하는데, 이 객체는 원소를 순환할 때 LinkedHashMap이 실제로 조작된 횟수(modCount)와 순환이 시작될 때 확인된 조작된 횟수(expectedModCount)의 값을 비교해 만약 두 값이 일치하지 않으면 ConcurrentModificationException을 발생시킨다. abstract class LinkedHashIterator { ... int expectedModCount; ... final LinkedHashMap.Entry nextNode..
코틀린의 양의 정수 타입 일반적인 다른 언어들과 같이 코틀린에서도 부호 없는 정수(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..
lateinit 이란 무엇이며 언제 사용해야 하는가? 다음과 같은 NonNullableValueStateHolder 클래스를 살펴보자. *실제 코틀린에서는 아래와 같이 getter와 setter을 직접 설정하는 경우가 거의 없다. class NonNullableValueStateHolder() { private var nonNullableValue: String = "testValue" fun set(value: String) { nonNullableValue = value } fun get(): String { return nonNullableValue } } 이 클래스에는 nonNullableValue 라 불리는 String 타입의 non-nullable한 값이 있고, 이 변수에는 "testValue..
컬렉션 연산의 문제와 Sequence의 지연 계산을 통한 해결 컬렉션 연산의 문제 컬렉션을 사용해 람다 연산을 하게 되면 비효율적으로 동작한다. 예를 들어 컬렉션(리스트)에서 가장 먼저 나오는 짝수값을 찾고 싶다고 해보자. 이런 코드는 다음과 같이 작성될 수 있다. fun main() { val collection = listOf(1, 2, 3, 4, 5, 6, 7, 8) val result = collection.filter { println("filter >> $it 은 짝수인가? >> ${it % 2 == 0}") it % 2 == 0 // 짝수만 필터링 }.first() println(result) } 이렇게 작성된 코드가 어떻게 동작하는지 코드를 실행해 확인해 보자. 그러면 다음과 같은 결과를 ..