Kotlin Couroutine 기본 개념

목표 코루틴의 기본 개념을 이해한다. 코투린을 사용하기 위한 기본 kotlin 문법을 이해한다. 코루틴 특정 코드 블럭을 다른 커드와 동시에 실행한다는 점에서 스레드와 비슷하다. 하지만 코루틴은 특정 스레드에 바인딩되지 않는다. 한 스레드에서 실행을 일시 중지했다가 다른 스레드에서 다시 시작할 수 있다. 스레드를 사용하면 메모리를 많이 소모하게되지만, 코루틴은 JVM에서 사용 가능한 메모리 제한에 부딪히지 않고 표현할 수 있다. fun main() = runBlocking { // this: CoroutineScope launch { // launch a new coroutine and continue delay(1000L) // non-blocking delay for 1 second (default time unit is ms) println("World!...

2025-03-18 · 2 min · 397 words

JsonPath 문법

배경 통합 테스트에서 WebTestClient를 사용하고 있는데 응답 바디 assertion에서 내부적으로 JsonPath 방식으로 응답 바디의 경로를 지정해 검증하고 있다. 좀 더 유연한 테스트 코드 작성을 위해 JsonPath 표현식 작성법을 이해한다. 표기법 JsonPath 표현식에는 2가지의 표기법이 존재한다. 점 표기법: $.players[0].nickname 괄호 표기법: $['players'][0]['nickname'] 연산자 연산자 설명 $ 루트 노드 @ 처리하고 있는 현재 노드 * 와일드카드. 숫자나 이름이 필요한 모든 곳에서 사용 가능하다. .. Deep scan. 이름이 필요한 모든 곳에서 사용 가능하다. ....

2024-11-06 · 2 min · 385 words

Sealed 클래스의 서브 클래스 모두 가져오기

sealedSubclasses KClass의 프로퍼티로 sealedSubclasses라는 프로퍼티가 존재한다. 현재 호출하는 클래스가 Sealed 클래스이면 이를 상속한 하위 클래스들이 반환되고, 아니면 빈 리스트가 반환된다. 예시 sealed class Animal class Dog : Animal() class Cat: Animal() class Duck: Animal() class Tests { @Test fun test() { println(Animal::class.sealedSubclasses) } } 아래와 같은 결과를 확인할 수 있다. [class com.tests.Cat, class com.tests.Dog, class com.tests.Duck] 참고 자료 https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-class/sealed-subclasses.html https://www.baeldung.com/kotlin/subclasses-of-sealed-class

2024-10-02 · 1 min · 60 words

KClass로 object 클래스의 인스턴스 가져오기

objectInstnace KClass의 인스턴수 중에 objectInstance가 존재한다. 현재 클래스가 object 클래스이면 해당 인스턴스가 반환되고, 아니면 null이 반환된다. 예시 object ObjectClass class SomeClass class Tests { @Test fun test() { assertThat(ObjectClass::class.objectInstance).isEqualTo(ObjectClass) assertThat(SomeClass::class.objectInstance).isNull() } } 참고 자료 https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-class/object-instance.html

2024-10-02 · 1 min · 35 words

중위 함수

목표 중위 함수 구현 방법을 알아본다. infix 중위 함수로 만들고자 하는 함수 앞에 infix 키워드를 붙이면 된다. 단, 3가지 조건이 있다. 함수가 클리스에 구현되어 있거나, 특정 클래스의 확장 함수이다. 함수는 정확히 하나의 파라미터를 가진다. 함수 앞에 infix 키워드가 붙어있다. data class Point(val x: Int, val y: Int) { infix fun isEqualTo(other: Point): Boolean { return x == other.x && y == other.y } } Point(1, 2) isEqualTo Point(1, 2) 참고 자료 https://www....

2024-09-15 · 1 min · 72 words

property vs function

배경 코틀린 스터디 중에 커스텀 접근자(프로퍼티)와 함수를 언제 사용하면 좋을지 고민하는 시간을 가졌다. 코틀린 공식 문서 코틀린 공식 문서의 코딩 컨벤션에서는 아래의 경우 프로퍼티를 사용하는 것을 권장하고 있다. 예외를 던지지 않는다. 계산이 복잡하지 않다. (또는 최초 실행 결과가 캐시된다) 객체의 상태가 변경되지 않는 경우 호출에 대해 동일한 결과를 반환한다. 내 생각 프로퍼티를 객체의 상태를 표현하는 용도로 사용하는 것이 가장 적절하다는 생각이 들었다. 코틀린 공식 문서에서 제공하고 있는 가이드가 객체의 상태를 표현할 때만 사용한다면 위배되지 않는다....

2024-09-15 · 1 min · 78 words

List에서 element 개수 Map으로 만들기

목표 [1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 5, 5, 5]의 경우, {1=2, 2=2, 3=1, 4=3, 5=5} 로 만들어주는 로직이 필요했다. groupingBy 코틀린 확장 함수 keySelector라는 함수를 함수를 명시해서 각 element에 key를 추출한다. key별로 그룹핑한 값들을 Grouping<T, K> 클래스로 래핑한다. T가 원래 타입, K가 key의 타입이 된다. Grouping<T, K> 클래스에서 eachCount()를 호출하면 각 그룹의 element 개수를 Map<K, Int> 형태로 반환한다. val words = "one two three four five six seven eight nine ten"....

2024-09-15 · 1 min · 99 words

Language Injections

목표 IntelliJ의 Language injections 기능이 무엇인지 이해한다. Language injections 사용 방법을 이해한다. Language injections 코드 내에 일부분을 다른 언어로 코드 어시스턴트를 받을 수 있는 기능 사용법 임시로 language injection 사용 원하는 영역에서 ⌥(Opt) + ↩(Enter)를 누르고, “Inject language or reference"를 누른다. 영구적으로 language injection 사용 원하는 영역에 @Language 애노테이션을 붙이면 IntelliJ에서 자동으로 language injection을 해준다. 적용 전 적용 후 참고 자료 https://www.jetbrains.com/help/idea/using-language-injections.html#language_annotation

2024-09-15 · 1 min · 62 words

Kotlin에서 getClass()

배경 Java에서 Class<T> 타임을 파라미터로 받는 메서드를 코틀린에서 사용할 필요가 있었다. KClass 코틀린에서는 Class<T>와 비슷하게 KClass<T>를 제공하고 있다. 아래와 같은 방식으로 타입을 얻을 수 있지만 Class<T>와는 같지 않다. String::class 자바의 타입을 얻고 싶다면, 아래와 같이 kotlin.jvm에서 제공하고 있는 확장 프로퍼티를 이용할 수 있다. String::class.java

2024-09-15 · 1 min · 44 words

Kotlin과 Java 혼용시 Checked Exception 알려주기

상황 코틀린에서는 Checked Exception을 따로 처리해주지 않는다. 자바에서 Checked Exception을 catch 해서 처리해주고 싶은데 이가 문제가 되었다. 해결 방법 코틀린에 @Throws 어노테이션을 사용하면 자바에서 checked exception 처리가 가능해진다. @Throws(IOException::class) fun foo() { throw IOException() } 참고 자료 https://kotlinlang.org/docs/java-to-kotlin-interop.html#checked-exceptions https://stackoverflow.com/questions/36528515/throws-exception-in-a-method-with-kotlin

2024-09-15 · 1 min · 39 words

Kotlin takeIf

목표 takeIf() 함수의 목적을 이해한다. takeIf inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? predicate가 true면 this를 리턴하고, false면 null을 리턴한다. 참고 자료 https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/take-if.html

2024-09-15 · 1 min · 24 words

Kotlin Contracts

목표 Kotlin contracts가 무엇인지 이해한다. Kotlin contracts의 사용법을 이해한다. 배경 아래 사진과 같이 validate() 함수에서 request의 null 검사를 했음에도 불구하고, process는 다른 함수여서 스마트 캐스트가 이루어지지 않는다. Kotlin contracts를 사용하면 이 문제를 해결할 수 있다. Kotlin contracts는 컴파일러에게 함수의 동작을 알려준다. 스마트 캐스트 contract() 메서드를 호출되는 함수에 선언하고, 내부에 함수의 동작을 명시한다. returns(): 함수가 정상적으로 리턴되는 경우를 의미한다. implies(): 파라미터로 받은 booleanExpression이 항상 참임을 보장한다. 실험적인 단계의 contract API를 사용하는 함수에는 @OptIn(ExperimentalContracts:class)를 붙여주거나 컴파일 인자로 -opt-in=kotlin....

2024-09-15 · 1 min · 183 words

isLetter 사용 시 주의점

배경 문자열이 영어로만 이루어져 있는지 확인하기 위해서 isLetter 함수를 사용하면 놓칠 수 있는 문제점이 있다. fun String.onlyAlphabetChars() = this.asSequence().all { it.isLetter() } isLetter() 공식 문서를 확인해보면 isLetter()은 문자 카테고리가 UPPERCASE_LETTER, LOWERCASE_LETTER, TITLECASE_LETTER, MODIFIER_LETTER, OTHER_LETTER 중 하나면 true를 반환한다. 이런 UPPERCASE_LETTER, LOWERCASE_LETTER 등에는 단순 알파벳인 a-z, A-Z 뿐만 아니라 Ä, Ë 등도 카테고리에 포함된다. https://www.compart.com/en/unicode/category/Lu a-z, A-Z만 가능하게 만드려면 해당 함수를 사용하면 안된다. 참고 자료 https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/is-letter.html#kotlin.text https://www.baeldung.com/kotlin/remove-non-alphanumeric-characters https://www.baeldung.com/java-character-isletter-isalphabetic

2024-09-15 · 1 min · 67 words

Enum 생성자에서 companion object 함수 호출

배경 개발 중인 프로젝트의 kotlin 버전을 1.5.30에서 1.9.0으로 올렸는데, 컴파일 에러가 발생했다. 에러 내용은 Companion object of enum class ... is uninitialized here 으로, 아래 사진과 같이 enum의 생성자 부분에서 enum class의 companion object 함수를 호출하지 못하고 있었다. 원인 분석 kotlin 1.9.0 이전 버전에서 이런 구조는 런타임에 NullPointerException나 ExceptionInInitializerError가 발생할 가능성이 존재했다. kotlin 1.9.0 에서 이를 해결하기 위해 컴파일 타임에 enum 생성자에서 companion object를 호출하는 것을 막도록 수정되었다. 참고 자료 https://kotlinlang....

2024-09-15 · 1 min · 72 words

Enum class의 entries 프로퍼티

목표 Enum 클래스의 entries 프로퍼티가 무엇인지 이해한다. 기존에 있던 Enum values() 메서드와 차이점을 이해한다. entries kotlin 1.9.0부터 enum 모든 값을 반복해서 처리하고 싶은 경우 entries 프로퍼티를 사용할 수 있다. CardType.entries.forEach { println(it.code) } values()와 차이점 values() 호출시마다 배열을 생성하고 복제한다. (상대적으로 성능이 나쁨) mutable 하다. Array 타입 반환으로 kotlin의 확장 함수를 사용하기 불편하다. entries 미리 생성된 리스트를 반환한다. immutable List를 상속한 EnumEntries를 반환하여 kotlin의 확장 함수들을 사용하기 용이하다. 참고 자료 https://www....

2024-09-15 · 1 min · 73 words

Duque 사용하기

목표 kotlin에서 deque을 사용하는 방법을 알아본다. ArrayDeque kotlin에서 제공하는 배열기반의 Deque 구현체다. LinkedList와 비교했을 때 메모리 오버헤드가 적고 런타임 속도가 더 빠르다. 사용법 생성 val deque = ArrayDeque(listOf(1, 2, 3, 4)) 추가 deque.addFirst(1) // 앞 deque.addLast(5) // 뒤 제거 removeFirst, removeLast의 경우 요소가 존재하지 않으면 NoSuchElementException 예외가 발생한다. deque.removeFirst() deque.removeLast() deque.removeFirstOrNull() deque.removeLastOrNull() 참고 자료 https://www.baeldung.com/kotlin/arraydeque

2024-09-15 · 1 min · 55 words

data class 프로퍼티로 Array가 있는 경우 equals를 오버라이드 하는 이유

상황 data 클래스에 Array 타입의 프로퍼티가 있을 경우에 IDE에서 equals()와 hashCode()를 오버라이드 하라는 알림이 나온다. 원인 data 클래스는 equals()를 자동 생성할 때, 각 프로퍼티의 equals() 메소드를 호출하여 동등성을 비교한다. 아래 사진은 위의 SomeClass를 자바로 디컴파일 한 코드다. Instrinsics.areEqual() 코드를 살펴보면 두 객체의 equals()를 호출하는 것을 확인할 수 있다. Array 타입은 equals() 메소드가 구현되어 있지 않으므로, 오버라이드 해줘야된다. 만약 List 를 사용할 수 있는 상황이라면 Array 대신 List로 대체하는 방법도 있다. 참고 자료 https://stackoverflow....

2024-09-15 · 1 min · 73 words