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")

다음은?

0개의 댓글