ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 코틀린 기초
    Kotiln 2019. 7. 23. 15:33

    코틀린의 특성

    • 함수를 선언할 때 fun 키워드를 사용한다.
    • 파라미터 이름 뒤에 그 파라미터의 타입을 쓴다.
    • 함수를 최상위 수준에 정의할 수 있다.
    • 배열로 일반적인 클래스와 마찬가지다.
    • 여러 가지 표준 자바 라이브러리 함수를 간결하게 사용할 수 있게 wrapper 를 제공한다. (System.out.println -> println )
    • 줄 끝에 세미콜론을 붙이지 않아도 된다.

    함수

    함수 선언은 fun 키워드로 시작하며 fun 다음에는 함수 이름이 온다.
    함수 이름 뒤에는 괄호 안에 파라미터 목록이 온다. 함수의 반환 타입은 파라미터 목록의 닫는 괄호 다음에 오는데 괄호와 반환 타입 사이를 콜론(:)으로 구분해야 한다.

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

    문(statement) 과 식(expression)의 구분
    코틀린에서 if 는 식이지 문이 아니다. 식은 값을 만들어 내며 다른 식의 하위 요소로 계산에 참여할 수 있는 반면 문은 자신을 둘러싸고 있는 가낭 안쪽 블록의 최상위 요소로 존재하며 아무런 값을 만들어내지 않는다는 차이가 있다. 자바는 모든 제어 구조가 문인 반면 코틀린에서는 루프를 제외한 대부분의 제어 구조가 식이다.

    식이 본문인 함수

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

    본문이 중괄호로 둘러싸인 함수를 블록이 본문인 함수라 부르고
    등호와 식으로 이뤄진 함수를 식이 본문인 함수라고 부른다.
    식이 본문인 함수는 컴파일러가 식을 분석해서 식의 결과 타입을 함수 반환 타입으로 정해준다. 이런 기능을 타입 추론type inference 라고 한다.

    변수

    자바에서는 변수를 선언할 때 타입이 맨 앞에 오지만 코틀린에서는 타입 지정을 생략할 수 있다.

    val foo = "str..."
    val bar = 42 // val bar: Int = 42 와 같다

    변수 선언 시 사용하는 키워드는 2가지 이다.
    val변경 불가능한 참조를 저장하는 변수이다. 일단 초기화하고 나면 재대입이 불가능하다. 자바로 말하면 final 변수에 해당한다.
    var변경 가능한 참조이다. 자바의 일반 변수에 해당한다. 변수의 값은 변경할 수 있지만 타입은 고정돼 바뀌지 않는다.

    문자열 템플릿

    변수를 문자열 안에 사용할 수 있다. 문자열 리터럴의 필요한 곳에 변수를 넣되 변수 앞에 $ 를 추가해야 한다.

    val name = "Kotlin"
    println("Hello, $name!")

    한글을 문자열 템플릿에서 사용할 경우 $로 변수를 지정할 때 변수명 바로 뒤에 한글을 붙여서 사용하면 코틀린 컴파일러는 영문자와 한글을 한꺼번에 식별자로 인식해서 unresolved reference 오류를 발생시킨다.
    이 문제를 해결하는 방법은 변수 이름을 { } 로 감싸는 것이다.

    클래스와 프로퍼티

    public class Person{
        private final String name;
    
        public Person(String name){
            this.name = name;
        }
    
        public String getName(){
            return name;
        }
    }

    자바에서 정의한 Person 클래스를 코틀린으로 변환하면 다음과 같다.

    class Person(val name: String)

    코틀린의 기본 가시성은 public 이므로 이런 경우 생략해도 된다.

    프로퍼티

    자바에서는 필드와 접근자를 묶어 프로퍼티라고 부르며 코틀린 프로퍼티는 자바의 필드와 접근자 메소드를 완전히 대신한다.
    val로 선언한 프로퍼티는 읽기 전용이며 var로 선언한 프로퍼티는 변경 가능하다.
    코틀린은 gettersetter를 자동으로 생성한다.

    커스텀 접근자

    class Rectangle(val height: Int, val width: Int){
        val isSquare: Boolean
            get() {
                return height == width
            }
    }

    enum

    코틀린에서 enum소프트 키워드 이다. enumclass 앞에 있을 때는 특별한 의미를 지니지만 다른 곳에서는 이름을 사용할 수 있다.

    enum class Color {
        RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
    }

    enum은 단순히 값만 열거하는 존재가 아니며 enum 클래스 안에도 프로퍼티나 메소드를 정의할 수 있다.

    enum class Color(val r: Int, val g: Int, val b: Int) {
        RED(255, 0, 0),
        ORANGE(255, 165, 0),
        YELLOW(255, 255, 0),
        GREEN(0, 255, 0),
        BLUE(0, 0, 255),
        INDIGO(75, 0, 130),
        VIOLET(238, 130, 238);
    
        fun rgb() = (r * 256 + g) * 256 + b
    }

    enum 클래스 안에 메소드를 정의하는 경우 반드시 enum 상수 목록과 세미콜론을 넣어야 한다.

    enum

    when 은 자바에서의 switch에 해당한다. when을 이용하여 enum 클래스를 다룰 수 있다.

    fun getMnemonic(color: Color) =
        when (color) {
            Color.RED -> "Richard"
            Color.ORANGE -> "Of"
            Color.YELLOW -> "York"
            Color.GREEN -> "Gave"
            Color.BLUE -> "Battle"
            Color.INDIGO -> "In"
            Color.VIOLET -> "Vain"
        }
    
    println(getMnemonic(Color.Blue))
    > Battle

    자바와 달리 각 분기의 끝에 break를 넣지 않아도 된다.
    when 식의 인자로 아무 객체나 사용할 수 있다.

    각 분기의 조건이 boolean 결과를 계산하는 식이라면 when에 아무 인자도 넣지 않을 수 있다.

    스마트 캐스트

    코틀린에서는 is를 사용해 변수 타입을 검색한다. 자바의 instanceof와 비슷하지만 is는 타입을 검사 후 따로 캐스팅하지 않아도 처음부터 그 변수가 원하는 타입으로 선언된 것 처럼 사용할 수 있다.

    명시적으로 타입 캐스팅하려면 as 키워드를 사용한다.

    while 루프

    코틀린에는 whiledo-while 루프가 있다. 문법은 자바와 다르지 않다.

    범위

    코틀린에는 자바의 for 루프에 해당하는 요소가 없다. 따라서 코틀린에서는 범위range를 사용한다.
    범위는 기본적으로 두 값으로 이뤄진 구간이다.
    .. 연산자로 시작 값과 끝 값을 연결해서 범위를 만든다.

    val oneToTen = 1..10

    step 으로 증가 값을 설정할 수 있다.
    downTo를 붙이면 역방향 수열을 만든다.

    100 downTo 1 step 2 

    until 함수를 사용하면 끝 값을 포함하지 않는 범위를 만들 수 있다.

    for(x in 0 until size) // for (x in -..size-1) 과 같다

    맵에 대한 이터레이션

    val binaryReps = TreeMap<Char, String>()
    for (c in 'A'...'F') {
        val binary = Integer.toBinaryString(c.toInt())
        binaryReps[c] = binary
    }
    for ((letter, binary) in binaryReps) {
        println("$letter = $binary)
    }

    get, put 을 사용하는 대신 map[key]map[key] = value 를 사용해 값을 가져오고 설정할 수 있다.

    in으로 컬렉션이나 범위의 원소 검사

    in 연산자를 사용해 어떤 값이 범위에 속하는지 검사할 수 있다.
    반대로 !in을 사용하면 어떤 값이 범위에 속하지 않는지 검사할 수 있다.

    fun isLetter(c: Char) = c in 'a'..'z' || c in 'A'..'Z'
    fun isNotDigit(c: Char) = c !in '0'..'9'
    
    println(isLetter('q'))
    > true
    println(isNotDigit('x'))
    > true

    in!in 연산자를 when 식에 사용해도 된다.

    fun recognize(c: Char) = when(c) {
        in '0'..'9' -> "It's a digit!"
        in 'a'..'z', in 'A'..'Z' -> "It's a letter"
        else -> "I don't know.."
    }
    
    println(recognize('0'))
    > It's a digit!

    예외 처리

    코틀린의 예외처리는 자바나 다른 언어의 예외 처리와 비슷하다. 함수는 정상적으로 종료할 수 있지만 오류가 발생하면 예외를 던질throw 수 있다.

    if(percentage !in 0..100){
        throw IllegalArgumentException(
            "A percentage value must be between 0 and 100: $percentage")

    try, catch, finally

    자바와 가장 큰 차이는 throws 절이 없다는 점이다.
    체크 예외와 언체크 에외를 구별하지 않는다.

    자바에서 사용하는 try-with-resource 구문은 코틀린에서 제공되지 않는다.
    대신 use 함수를 이용한다.

    fun readFirstLineFromFile(path: String): String{
        BufferedReader(FileReader(path)).use { br ->
            return br.readLine()
        }
    }
    반응형

    댓글 0

Designed by Tistory.