2023년 1월 22일 일요일

Kotlin Tip

Kotlin Tip

Kotlin Tip 모음

Kotlin DSL

Kotlin은 DSL 은 아래의 자료를 참고

Kotlin Koin

Kotlin은 Koin 은 아래의 자료를 참고

Kotlin Ktlint

Kotlin은 ktlint 은 아래의 자료를 참고
Kotlin은 ktlint&git hook 연동은 은 아래의 자료를 참고

Collection

map: List 에서 특정 필드만 다시 List로 바꿔주기

Collection 클래스에는 map 이라는 기능이 있어서 소스 List의 각 요소에 변환(transform) 처리한 결과값을 List형태로 돌려 받을수 있다.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map.html

data class hehe ( val id: Long = -1L, val name: String)

myData.map { it.id } ==> List<Long>
myData.map { it.name } ==> List<String>

General

Sealed Interface를 사용해야 되는 이유

Sealed 클래스는 프로그램 표준이 되어도 좋다고 생각할 정도로 유용하다.
Sealed Class와 같은 형태로 선언하고 사용하는데 Sealed Interface를 사용하면 사용되는 메모리를 절반으로 줄일수 있다고 한다.
Sealed 를 사용할때는 인터페이스로 가능하다면 인터페이스우선으로 설계하자.
https://medium.com/@omurkumru/sealed-classes-sealed-interfaces-and-enum-classes-in-kotlin-8df3abacbe4c

Min,Max를 사용하지 않고 CoerceIn을 사용하여 범위내의 수로 제한하기

coerceIn을 사용하면 Min, Max를 사용하지 않고도 깔끔하게 값을 일정범위내로 제한할수있다.
단, 음수일때는 소괄호로 묶어줘야 한다. 이거…에러가 될 소지가 높으니 조심.!!

13.coerceIn(0,  10)  //10  또는 coerceIn(0..10) 처럼범위함수 사용가능
(-13).coerceIn(0,  10)  //0  
4.coerceIn(0,  10)  //4
'''
그밖에 아래의 두가지 함수가 있다.
coerceAtLeast(리시버의 값이 지정값이하일때는지정값으로 무조건 정함) 
coerceAtMost(리시버의 값이 지정값이상일때는지정값으로 무조건 정함) 

### until 을 활용하여 코드를 깔끔하게
val ERROR_AA = 1 until 5
val ERROR_BB = 10 until 50
--> in AA -> { , in BB -> {

### 단일표현식함수
```kotlin
//개선전
fun double(x: Int): Int { 
    return x * 2
}

//개선후
fun double(x: Int): Int = x * 2

범위함수

범위가 지정된 함수에는 let , run , with , apply 및 also 의 다섯 가지 유형이 있습니다 .

//개선전
var rectangleB = Rectangle()
rectangleB.length = 4
rectangleB.breadth = 5
rectangleB.color = 0xFAFAFA
rectangleB.padding = 2

//개선후
var rectangleB = Rectangle().apply {
    length = 4
    breadth = 5
    color = 0xFAFAFA
    padding = 2
}

컬렉션생성자

kotlin은 쉽고 빠르게 집합을 생성할 수 있는 표준 라이브러리 기능을 제공합니다…

//개선전
val listA = ArrayList<String>()
listA.add("one")
listA.add("two")
listA.add("three")
listA.add("four")

//개선후
val listB = mutableListOf("one", "two", "three", "four")

집합연산자

kotlin에서 제공하는 집합 연산자를 사용하면 편리합니다.
kotlin 프로젝트에서 _Collections.kt 파일을 검색하고 열어 더 많은 컬렉션 연산자를 볼 수 있습니다. 또한 컬렉션에서 작업할 때 이 파일로 이동하여 적합한 연산자가 있는지 확인하는 것이 좋습니다

//개선전
var firstBigLengthElementA = ""
for (e in listA) {
    if (e.length > 3) {
        firstBigLengthElementA = e
        break
    }
}

//개선후
var firstBigLengthElementB = listA.first { it.length > 3 }

지연 속성/초기화

지연 속성 lazy는 kotlin에서 제공하는 델리게이트 속성 중 하나로, kotlin 델리게이트 속성에 대해서는 다음 글에서 자세히 설명하도록 하겠습니다.

lazy()는 람다를 받아 속성의 대리자로 사용할 수 있는 Lazy 인스턴스를 반환하는 함수입니다.

대리자 속성 + 지연 메서드를 사용하여 속성의 지연된 초기화를 실현할 수 있음을 간단히 이해할 수 있습니다.


data class Person(
    val name: String,
    val age: String,
    val sex: String
) {
    init {
        println("person onCreate")
    }
}


class Test {
    //개선전
    val personA: Person = Person("name", "age", "girl")

    //개선후
    val personB: Person by lazy {
        println("lazy create person")
        Person("name", "age", "girl")
    }
    
    init{
        println("Test class onInit")
    }

    fun test() {
        println("A's age is:${personA.age}")
        println("B's age is:${personB.age}")
    }
}



fun main() {
    Test().test()
}

유형 별칭 - typealias

typealias는 기존 유형에 대한 대체 이름을 제공합니다. 유형 이름이 너무 길면 더 짧은 이름을 추가로 도입하고 원래 유형 이름을 새 이름으로 바꿀 수 있습니다.

이 키워드는 복잡한 제네릭 유형 또는 매개변수 정의가 더 많은 함수 유형에 사용할 수 있습니다. 복잡한 유형 정의 행을 매우 짧게 만들고 유형 정의를 사용하는 코드를 훨씬 더 간결하게 만들 수 있습니다.

//개선전
val fileTableA: MutableMap<Long, MutableList<File>>? = null
fun getTestFileTableA(): MutableMap<Long, MutableList<File>>? = fileTableA

//개선후
typealias FileTable<K> = MutableMap<K, MutableList<File>>
val fileTableB: FileTable<Long>? = null
fun getTestFileTableB(): FileTable<Long>? = fileTableB

고차함수로 전략 패턴을 단순하게 구현가능


class Worker(private val strategy: () -> Unit) {
    fun work() {
        println("START")
        strategy.invoke()
        println("END")
    }
}


fun testStrategy() {
    val worker1 = Worker({
        println("Do A Strategy")
    })
    val bStrategy = {
        println("Do B Strategy")
    }
    val worker2 = Worker(bStrategy)
    worker1.work()
    worker2.work()
}

0 comments:

댓글 쓰기