공식 문서로 보는 Kotlin 문법 찍먹 (1)

업데이트:

공식 문서에 나온 내용을 정리한 글.

자바와 완전히 동일하거나 매우 간단한 내용은 공식 문서를 통해 확인해도 좋을 거 같다. 예시 코드에 대한 결과도 확인할 수 있으니 코드의 플레이 버튼을 눌러보도록 하자.

Basics

Basic syntax

Program entry point

fun main() {
    println("Hello world!")
}

or

fun main(args: Array<String>) {
    println(args.contentToString())
}

main 함수를 보면 java와는 다르게 접근 제어자, static, return값이 보이지 않는다. 코틀린 접근 제한자(Visibility Modifier)는 public, protected, private, internal이 있다.

접근 제한자 내용
public 어디서나 접근 가능, 기본 접근 제한자
protected private 범위에서 자식 클래스 추가
pirvate 파일 또는 클래스 내
internal 같은 모듈 내

코틀린에선 따로 명시하지 않으면 public이다.

Functions

fun sum(a: Int, b: Int): Int {
    return a + b
}

fun sum(a: Int, b: Int) = a + b

fun printSum(a: Int, b: Int): Unit {
    println("sum of $a and $b is ${a + b}")
}
fun 함수명(파라미터): 반환값 {
		...
}

fun 함수명 (파라미터) = ...  // 함수 본문을 표현식으로 나타냄

fun 함수명(파라미터): Unit { // 반환값 없을 때 사용, 생략 가능
		...
}

Variables

val

읽기 전용은 val를 사용한다. java의 final 키워드를 붙인 것과 유사하다.

val a: Int = 1  // 즉시 할당
val b = 2   // 타입 명시
val c: Int  // 초기화 없이 타입만 명시
c = 3       // 지연 할당

값을 한번만 할당할 수 있다. 자바로 비교하면

final int a = 1;
final int b = 2;
int c;
c = 3;

var

var x = 5 // 'Int' 타입 유추
x += 1

// top level에 변수 선언
val PI = 3.14
var x = 0

fun incrementX() {
    x += 1
}

Createing classes and instances

class 키워드를 사용해 class를 정의한다.

class Rectangle(var height: Double, var length: Double) {
    var perimeter = (height + length) * 2
}

val rectangle = Rectangle(5.0, 2.0)
println("The perimeter is ${rectangle.perimeter}")

상속은 :을 통해 나타낸다. 코틀린에서 클래스는 기본으로 final이기 때문에 상속을 하기 위해선 부모 클래스에 open 키워드를 추가해야 한다.

open class Shape

class Rectangle(var height: Double, var length: Double): Shape() {
    var perimeter = (height + length) * 2
}

String template

문자열 안에서 외부의 변수를 가져올 때 사용한다. $를 붙여 사용한다.

var a = 1
val s1 = "a is $a" 

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

Conditional expressions

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

or 

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

if문 또한 표현식으로 나타낼 수 있다.

for loop

기본적인 foreach 반복문이다. 자바에 비해 보다 간결한 느낌이 든다.

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

인덱스를 이용하고 싶으면 .indices를 이용한다.

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

range를 조절해서 반복문을 실행하고 싶을 땐 step을 이용한다.

for (i in 1..3) {
    println(i)
}
// 결과
// 1 2 3 (println이라 실제론 한 줄에 하나지만 편의상 한 줄에 작성)

for (i in 6 downTo 0 step 2) {
    println(i)
}
//결과
// 6 4 2 0

when expression

when은 여러 분기가 있는 조건식에 사용한다. 자바의 switch과 유사하다.

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

when이 표현식으로 사용되는 경우 컴파일러가 모든 가능한 경우에 대해 커버하고 있는지를 확신할 수 없는 경우, else 분기는 필수로 있어야 한다. 즉, 모든 가능한 경우에 대한 조건이 없는 경우 else가 필수이다.

Nullable values and null checks

null 값이 가능한 경우, 참조를 nullable로 명시적으로 나타내야한다. Nullable 형식 이름에는 끝에 ?가 붙는다.

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

위 함수에서 str이 Int값이 없으면 null을 반환하게 된다.

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로 cast 된다.
        println(x * y)
    }
    else {
        println("'$arg1' or '$arg2' is not a number")
    }    
}

Type checks and automatic casts

is연산자는 표현식이 type의 인스턴스인지 확인한다. 불변 지역 변수나 property가 특정 type으로 확인된 경우 명시적으로 캐스팅할 필요가 없다.

fun getStringLength(obj: Any): Int? {
    if (obj is String) {
        // `obj`는 자동으로 `String`으로 캐스팅 된다.
        return obj.length
    }

    // `obj`는 type-checked 분기를 지나서 `Any` type으로 존재한다. 
    return null
}

정리

코틀린의 기본적인 문법에 대해 공식 문서를 통해 정리해보았다. 물론 더 깊게 들어가면 많은 연산자와 표현 방법들이 존재할테지만 지금은 가볍게 찍먹해보겠다.

이를 기반으로 우아한테크코스 level1 미션이었던 racing-car를 코틀린으로 구현해보려고 한다

태그:

업데이트:

댓글남기기