본문 바로가기
개발&프로그래밍

[kotlin] 입문시 알아야 할 8가지 핵심 문법

by 재아군 2024. 8. 7.

 

Kotlin의 주요 문법 특징들을 간략히 정리한 것입니다.

각 항목은 Kotlin의 간결하고 표현력 있는 코드 작성을 지원하는 특징들을 보여줍니다.

 

아래 문서는 kotlinlang.org 공식 홈페이지를 참조합니다.

 

  1. 문자열 템플릿:
    • $변수명으로 간단한 변수 삽입
    • ${표현식}으로 복잡한 표현식 삽입 가능
  2. 조건식:
    • 일반적인 if-else 구문 사용
    • if를 표현식으로 사용 가능 (삼항 연산자 대체)
  3. 반복문:
    • for-in 루프로 컬렉션 순회
    • while 루프 사용 가능
  4. when 표현식:
    • switch-case 대체
    • 다양한 조건 체크 가능 (값, 타입 등)
  5. 범위:
    • in 연산자로 범위 내 포함 여부 확인
    • 범위를 이용한 반복 가능 (step, downTo 사용)
  6. 컬렉션:
    • for-in으로 순회
    • in 연산자로 포함 여부 확인
    • 람다 표현식으로 필터링, 정렬, 변환 등 가능
  7. Nullable 값과 null 체크:
    • ? 로 nullable 타입 표시
    • null 안전 호출 연산자 (?.) 사용
    • null 체크 후 자동 캐스팅
  8. 타입 체크와 자동 캐스트:
    • is 연산자로 타입 체크
    • 스마트 캐스트: 타입 체크 후 자동으로 해당 타입으로 취급

 

 

 

문자열 템플릿

var a = 1
// 템플릿의 단순 이름:
val s1 = "a is $a" 

a = 2
// 템플릿의 임의 표현식:
val s2 = "${s1.replace("is", "was")}, but now is $a"
 

조건식

fun maxOf(a: Int, b: Int): Int {
    if (a > b) {
        return a
    } else {
        return b
    }
}

 

Kotlin에서 if는 표현식으로도 사용될 수 있습니다

fun maxOf(a: Int, b: Int) = if (a > b) a else b

 

for 루프

val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
    println(item)
}

 

또는

val items = listOf("apple", "banana", "kiwifruit")
for (index in items.indices) {
    println("item at $index is ${items[index]}")
}

 

while 루프

val items = listOf("apple", "banana", "kiwifruit")
var index = 0
while (index < items.size) {
    println("item at $index is ${items[index]}")
    index++
}

 

when 표현식

fun describe(obj: Any): String =
    when (obj) {
        1          -> "One"
        "Hello"    -> "Greeting"
        is Long    -> "Long"
        !is String -> "Not a string"
        else       -> "Unknown"
    }

 

범위

in 연산자를 사용하여 숫자가 범위 내에 있는지 확인한다

val x = 10
val y = 9
if (x in 1..y+1) {
    println("fits in range")
}

 

숫자가 범위를 벗어났는지 확인한다

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

if (-1 !in 0..list.lastIndex) {
    println("-1 is out of range")
}
if (list.size !in list.indices) {
    println("list size is out of valid list indices range, too")
}

 

범위를 반복한다

for (x in 1..5) {
    print(x)
}

 

또는

for (x in 1..10 step 2) {
    print(x)
}
println()
for (x in 9 downTo 0 step 3) {
    print(x)
}

 

컬렉션

컬렉션을 반복한다

for (item in items) {
    println(item)
}

 

in 연산자를 사용하여 컬렉션에 객체가 포함되어 있는지 확인한다

when {
    "orange" in items -> println("juicy")
    "apple" in items -> println("apple is fine too")
}

 

람다 표현식을 사용하여 컬렉션 필터링 및 매핑한다

val fruits = listOf("banana", "avocado", "apple", "kiwifruit")
fruits
    .filter { it.startsWith("a") }
    .sortedBy { it }
    .map { it.uppercase() }
    .forEach { println(it) }

 

Nullable 값 및 null 체크

null 값이 가능한 경우 참조는 명시적으로 nullable로 표시되어야 합니다. Nullable 타입 이름은 끝에 ?가 있습니다.

str이 정수를 포함하지 않으면 null 반환한다

fun parseInt(str: String): Int? {
    // ...
}

 

nullable 값을 반환하는 함수 사용

fun printProduct(arg1: String, arg2: String) {
    val x = parseInt(arg1)
    val y = parseInt(arg2)

    // `x * y`를 사용하면 null을 포함할 수 있기 때문에 오류가 발생합니다.
    if (x != null && y != null) {
        // x와 y는 null 체크 후 자동으로 non-nullable로 캐스트됩니다
        println(x * y)
    }
    else {
        println("'$arg1' or '$arg2' is not a number")
    }    
}

 

또는

 

// ...
if (x == null) {
    println("Wrong number format in arg1: '$arg1'")
    return
}
if (y == null) {
    println("Wrong number format in arg2: '$arg2'")
    return
}

// x와 y는 null 체크 후 자동으로 non-nullable로 캐스트됩니다
println(x * y)

 

타입 체크 및 자동 캐스트

is 연산자는 표현식이 타입의 인스턴스인지 확인합니다. 불변의 지역 변수나 속성이 특정 타입으로 확인된 경우, 명시적으로 캐스트할 필요가 없습니다

 

fun getStringLength(obj: Any): Int? {
    if (obj is String) {
        // `obj` is automatically cast to `String` in this branch
        return obj.length
    }

    // `obj` is still of type `Any` outside of the type-checked branch
    return null
}

 

또는

 

fun getStringLength(obj: Any): Int? {
    if (obj !is String) return null

    // `obj` is automatically cast to `String` in this branch
    return obj.length
}

 

또는 

 

fun getStringLength(obj: Any): Int? {
    // `obj` is automatically cast to `String` on the right-hand side of `&&`
    if (obj is String && obj.length > 0) {
        return obj.length
    }

    return null
}

댓글