Kotlin v1.6.10 : Idioms

HH·2022년 2월 24일
0

Kotlin Docs v1.6.10

목록 보기
3/3

Idioms

번역문서 작성일 기준 Last modified: 30 November 2021
번역완료일 2022-02-24

코틀린에서 랜덤하고 자주 사용되는 idioms(관용구)의 모음. 좋아하는 idiom이 있다면 pull request로 contribute해 보자.


Create DTOs (POJOs/POCOs)


data class Customer (val name: String, val email: String)

아래 기능을 만족하는 Customer 클래스를 제공한다:

  • 모든 프로퍼티에 대한 getter(그리고 var의 경우 setter)
  • equals()
  • hashCode()
  • toString()
  • copy()
  • 모든 프로퍼티를 위한 component1(), component2(), ... (Data Classes를 보자)

Default values for function parameters


fun foo(a: Int = 0, b: String = "") {...}

Filter a list

val positives = list.filter {x -> x > 0}

또는 아래와 같이 더 짧게:

val positivies = list.filter { it > 0 }

자바와 코틀린 필터링 간 차이를 배우자.


collection에서 element 존재 여부 확인


if ("john@example.com" in emailsList) { ... }
if ("jane@example.com" in emailsList) { ... }

String interpolation


println("name $name")

자바와 코틀린 간 문자열 연결 차이점을 알아보자.


인스턴스 체크


when (x) {
    is Foo -> ...
    is Bar -> ...
    else -> ...
}

읽기 전용 리스트


val list = listOf("a", "b", "c")

읽기 전용 맵


val map = mapOf("a" to 1, "b" to 2, "c" to 3)

맵 앤트리 접근


println(map["key"])
map["key"] = value

맵 또는 쌍 리스트 탐색 (Traverse a map or a list of pairs)


for ((k, v) in map) {
    println("$k -> $v")
}

kvnameage같은 어떤 편리한 이름이든지 될 수 있다.


Iterate over a range


for (i in 1..100) {...} // closed range: 100 포함

for (i in 1 until 100) {...} // half-open range: 100을 포함하지 않음

for (i in 2..10 step 2) {...}

for (i in 10 downTo 1) {...}

(1..10).forEach {...}

Lazy property


val p : String by lazy {
    // string을 계산
}

확장 함수 (Extension functions)


fun String.spaceToCamelCase() {...}

"Convert this to camelcase".spaceToCamelCase()

싱글톤 생성


object Resource {
    val name = "name"
}

추상 클래스 인스턴스화


abstract class MyAbstractClass {
    abstract fun doSomething()
    abstract fun sleep()
}

fun main() {
    val myObject = object : MyAbstractClass () {
        override fun doSomething() {
            // ...
        }

        override fun sleep() { 
            // ...
        }
    }
    myObject.doSomething()
}

If-not-null shorthand


val files = File("Test").listFiles()

println(files?.size ?: "empty") //파일이 null이라면 empty를 프린트

null일 경우 명령문 실행


val values = ...
val email = values["email"] ?: throw IllegalStateException("email is missing")

비어있을 수 있는 컬렉션에서 첫 아이템 얻기


val emails = ... // 비어있을 수 있음
val mainEmail = emails.firstOrNull() ?: ""

자바와 코틀린 간 첫 아이템 획득 방식 차이점을 공부하자.


null이 아닐 경우 실행


val value = ...
value?.let {
    ... // null이 아니라면 이 블록을 실행한다.
}

when 문 리턴


fun transform(color: String): Int {
    return when (color) {
        "Red" -> 0
        "Green" -> 1
        "Blue" -> 2
        else -> throw IllegalArgumentException("Invalid color param value")
    }
}

try-catch 표현식


fun test() {
    val result = try {
        count ()
    } catch (e: AritmeticException) {
        throw IllegalStateException(e)
    }

    // 결과를 가지고 작업
}

if 표현식


val y = if (x == 1) {
    "one"
} else if (x == 2) {
    "two"
} else {
    "other"
}

Unit을 리턴하는 메서드의 빌더 스타일 사용법


 fun arrayOfMinusOnes(size: Int): IntArray {
     return IntArray(size).apply {fill(-1)}
 }

Single-expression functions


fun theAnswer() = 42

이것은 다음과 동일하다

fun theAnswer(): Int {
    return 42
}

이는 다른 idiom들과 효과적으로 결합되면서 더 짧은 코드를 이끌어 낼 수 있다. 예를 들어 when 표현식과 함께 사용할 수 있다:

fun transform(color: String): Int = when (color) {
    "Red" -> 0 
    "Green" -> 1
    "Blue" -> 2
    else -> throw IllegalArgumentException("Invalid color param value")
}

오브젝트 인스턴스에서 여러 메서드 호출 (with)


class Turtle {
    fun penDown()
    fun penUp()
    fun turn(degrees: Double)
    fun forward(pixels: Double)
}

val myTurtle = Turtle()
with(myTurtle) {
    // 100 픽셀 스퀘어를 그린다.
    penDown()
    for (i in 1..4) {
        forward(100.0)
        turn(90.0)
    }
    penUp()
}

오브젝트 프로퍼티 구성 (apply)


val myRectangle = Rectangle().apply {
    length = 4
    breadth = 5
    color = 0xFAFAFA
}

이것은 오브젝트 생성자에 존재하지 않는 프로퍼티를 설정할 때 유용하다.


java 7의 try-with-resources


val stream = Files.newInputStream(Paths.get("/some/file.txt"))
stream.buffered().reader().use { reader ->
    println(reader.readText())
}

제네릭 타입 정보를 요구하는 제네릭 함수


/* public final class Gson {
    ...
    public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException { }
    ...
} */

inline fun <reified T: Any> Gson.fromJson(json: JsonElement): T = this.fromJson(json, T::class.java)

Nullable Boolean


val b: Boolean? = ...
if (b == true) {
    ...
} else {
    // false 또는 null
}

두 변수 스왑하기


var a = 1
var b = 2
a = b.also { b = a }

코드를 미완성으로 만들기 (TODO)


코틀린 스탠더드 라이브러리는 언제나 NotImplementedError를 던지는 TODO() 함수를 가지고 있다. 이 리턴 타입은 Nothing이므로 예상하는 타입과 상관 없이 사용할 수 있다. reason parameter를 받는 오버로딩도 있다.

fun calcTaxes(): BigDecimal = TODO("Waiting for feedback from accounting")

다음은?

1개의 댓글

comment-user-thumbnail
2025년 1월 5일

Kotlin v1.6.10 continues to shine with its expressive and concise idioms, such as smart casts, null safety (?. and ?:), and powerful scoping functions like apply and let. Features like extension functions, destructuring declarations, and default arguments further streamline code readability and flexibility. These idioms, coupled with Kotlin's robust type system, make it a joy for developers to write clean, maintainable, and efficient code in a modern programming language.

답글 달기

관련 채용 정보