우주먼지
Published 2023. 3. 26. 02:23
Kotlin Basic Syntax Languages/Kotlin

💡 Basic Syntax

코틀린 기본 문법에 대해 IntelliJ를 이용해 학습한다.

 

함수 정의

함수를 생성할 때 리턴 값이 없는 경우 java/dart에서는 void로 생성해 주면 되지만,
kotlin에서는 Unit 이라는 형태로 생성해주거나 아무 것도 넣어주지 않으면 된다.

리턴 값이 있는 경우에는 리턴 타입을 넣어주면 된다.

/* ----- 함수 정의 ----- */

// 함수 바디가 식(Expression)인 경우 reutrn문 생략가능, return Type이 추론됨
fun sum(a: Int, b: Int) = a+b

// Java의 void역할을 하는 리턴 타입이 없는 Unit(Object)이 있으며, Unit은 생략이 가능하다.
fun print1(): Unit { println("Kotlin") }
fun print2() { println("Kotlin") }

 

변수 정의

변수를 선언할 때 실행 중 변할 수 있는 값을 변수라하고, 한 번 선언되면 변할 수 없는 값을 상수라고 한다.

Kotlin에서는 상수를 val(value)이라고 선언해 주면 되고, 변수에는 var(variable)이라고 선언을 해주면 된다.

 

참고로 Dart 언어에서는 변수에는 타입만 넣어주고 상수에는 final/const로 선언할 수 있는데,
final/const 차이는 실행 중 결정되냐 컴파일 시점에 결정되냐의 차이이다.

/* ----- 변수 정의 ----- */

fun Variable() {
    // val = Immutable 변수이며 읽기전용이고 선언시 초기화 필요.
    // (값 변경 불가능) Java의 final과 유사하다.
    val a: Int = 1
    val b = 2
    val c: Int // 컴파일 에러, 초기화 필요
    c = 3 // 컴파일 에러, 읽기 전용

    // var = Mutable 변수
    var x = 5
    x += 1
}

 

문자열 템플릿

/* ----- 문자열 템플릿 ----- */

// String Interpolation (문자열 보간법)
fun StringTemplate() : String {
    var a = 1
    val s1 = "a is $a"

    a = 2
    var s2 = "${s1.replace("is", "was")}, but now is $a"

    return s2
}

 

조건문

아쉽게도 Kotlin에는 삼항 연산자가 없다고 하여 이 부분은 조금 불편해 보이긴 하다.

kotlin 언어 조건문에는 when이라는 조건식이 있는데, dart의 switch 조건식과 유사하다.

 

if 문과 다르게 switch 문은 특정 case 만을 찾아서 한 번만 실행되기에 속도가 빠르다는 장점이 있는데,
kotlin의 when 조건식도 비슷한 장점이 있는게 아닐까 한다.

/* ----- 조건문 ----- */

// 조건문을 조건 식으로 변환 가능
fun max1(a: Int, b: Int): Int {
    if (a > b) {
        return a
    } else {
        return b
    }
}

// 조건 식(Expression)
fun max2(a: Int, b: Int) = if (a > b) a else b

 

Nullable Type

런타임 에러보다 컴파일 타임 에러를 통해 디버깅이 용이하다.

  • 모든 타입 + 기본형 타입도 클래스 타입이다. (Nullable을 위해)
  • 코틀린은 Null이 될 수 없는 값을 추적한다.
  • 실행 시점에 NPE가 발생할 수 있는 연산을 가진 코드를 금지한다.
  • 자바에서 객체의 Null 방어로직을 작성하는데 사용되는 많은 코드라인을 생략 가능하다.
/* ----- Nullable Type ----- */

// 값이 Null일 수 있는 경우 타입에 nullable을 '?' 기호를 사용해 명시
fun parseInt(str: String): Int? {
    // 정수가 아닌경우 null 리턴
    val value = str.toInt()
    return if (value !is Int) {
        null
    } else {
        value
    }
}

// Nullable 타입의 변수에 접근할 때 반드시 Null 체크를 해야함, 아니면 컴파일 에러 발생
fun printProduct(arg1: String, arg2: String) {
    val x: Int? = parseInt(arg1)
    val y: Int? = parseInt(arg2)

    if (x != null && y != null) {
        println(x * y)
    } else {
        println("either '$arg1' or '$arg2' is not a number")
    }
}

 

자동 타입 변환

/* ----- 자동 타입 변환 ----- */

// 타입 체크만 해도 자동으로 타입 변환, Any는 Object와 같은 의미이다
// obj가 스트링일때랑 length를 반환하며 String이 아니면 null 반환
fun getStringLength(obj: Any): Int? {
    if (obj is String) {
        return obj.length
    }
    return null
}

 

Loop & Collection

/* ----- Loop ----- */

// 자바와 거의 동일하다
fun loop() {
    val items = listOf("apple", "banana", "kiwi")
    var index = 0

    while (index < items.size) {
        println("item at $index is ${items[index]}")
        index++
    }
}

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

// Range - In 연산자를 이용해서 숫자 범위 체크
fun range() {
    val x = 3
    if (x in 1..10) {
        println("fits in range")
    }

    // range를 이용한 for loop
    for (x in 1..5) {
        print(x)
    }

    // 컬렉션 loop, 자바의 상향 for문과 비슷하다
    val items = listOf("apple", "banana", "kiwi")
    for (item in items) {
        println(item)
    }

    // In 연산자로 해당 값이 컬렉션에 포함되는지 체크
    val items2 = setOf("apple", "banana", "kiwi")
    when {
        "orange" in items2 -> println("juicy")
        "apple" in items2 -> println("apple is fine too")
    }

    // 람다식을 이용한 컬렉션의 filter, map 등 중간 연산
    val fruits = listOf("banana", "avocado", "apple", "kiwi")
    fruits
        .filter { it.startsWith("a") }
        .sortedBy { it }
        .map { it.toUpperCase() }
        .forEach { println(it) }
}

 

배열

kotlin 배열의 종류에는 Array/List/ArrayList 3개의 타입을 지원하는데,
배열 관련해서 추가로 알아볼 내용이 많아 자세한 내용은 다른 글에서 다시 다뤄보도록 하겠다.

 

간단하게 보면 Array 타입만 dart와 동일하게 인덱스에 접근해 값을 변경할 수 있는 반면 list 타입은 값을 꺼내 볼 수만 있고, arrayList 타입은 배열 함수를 통해서 값을 변경할 수 있다.

/* ----- Array ----- */

fun arrayAndList() {
    val array : Array<Int> = arrayOf(1,2,3,4,5)
    val list : List<Int> = listOf(1,2,3,4,5)
    val arrayList : ArrayList<Int> = arrayListOf<Int>()
    
    array[0] = 3
    list[1]
    arrayList.add(20)
}

 

profile

우주먼지

@o귤o

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그