ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 코틀린 타입 시스템 - 원시 타입
    Kotiln 2019. 7. 19. 17:44

    코틀린 타입 시스템 - 원시 타입

    원시 타입

    자바는 원시 타입 (int 등) 과 참조 타입 (String 등) 을 구분하고 참조 타입이 필요한 경우 원시 타입 갑을 래퍼 타입으로 감싸서 사용한다.
    코틀린은 원시 타입과 래퍼 타입을 구분하지 않으므로 항상 같은 타입을 사용한다.

    val i: Int = 1
    val list: List<Int> = listOf(1, 2, 3)

    더 나아가 코틀린에서는 숫자 타입 등 원시 타입의 값에 대해 메소드를 호출할 수 있다.

    대부분의 경우 코틀린의 Int 타입은 자바 int 타입으로 컴파일 된다. 컴파일이 불가능할 경우는 컬렉션과 같은 제네릭 클래스를 사용하는 경우뿐이다.

    null이 될 수 있는 원시타입

    null 참조를 자바의 참조 타입의 변수에만 대입할 수 있기 때문에 null 이 될 수 있는 코틀린 타입은 자바 원시 타입으로 표현할 수 없다. 따라서 코틀린에서 null 이 될 수 있는 원시 타입을 사용하면 그 타입은 자바의 래퍼 타입으로 컴파일된다.

    숫자 변환

    코틀린은 한 타입의 숫자를 다른 타입의 숫자로 자동 변환하지 않는다. 결과 타입이 허용하는 숫자의 범위가 원래 타입의 범위보다 넓은 경우조차도 자동 변환은 불가능하다.
    Boolean을 제외한 모든 원시 타입에 대한 변환 함수가 제공된다. toByte(), toShort()

    코틀린은 개발자의 혼란을 피하기 위해 타입 변환을 명시하기로 결정했다.
    두 박스 타입 간 equals 메소드는 그 안에 들어있는 값이 아니라 박스 타입 객체를 비교한다. 따라서 자바에서 new Integer(42).equals(new Long(42))false 이다.

    val x = 1
    val list = listOf(1L, 2L, 3L)
    x in list

    코틀린에서 위의 코드는 컴파일되지 않는다.

    val x = 1
    println(x.toLong() in listOf(1L, 2L, 3L))
    > true

    위의 코드 처럼 타입을 명시적으로 변환해서 같은 타입의 값으로 만든 후 비교해야 한다.

    숫자 리터럴을 사용할 떄는 보통 변환 함수를 호출할 필요가 없다. (42L, 42.0f)
    직접 변환하지 않아도 숫자 리터럴을 타입이 알려진 변수에 대입하거나 함수에게 인자로 넘기면 컴파일러가 필요한 변환을 자동으로 넣어준다.

    Any, Any? : 최상위 타입

    자바에서 object 가 클래스 계층의 최상위 타입이듯 코틀린에서는 Any 타입이 모든 null 이 될 수 없는 타입의 조상 타입이다. Int 등 원시 타입을 포함한 모든 타입의 조상 타입이다.
    null 을 포함하는 모든 값을 대입할 변수를 선언하려면 Any? 타입을 사용해야 한다.
    내부에서 Any 타입은 java.lang.Object 에 대응한다. 자바 메소드에서 Object 를 인자로 받거나 반환하면 코틀린에서는 플랫폼 타입인 Any!로 그 타입을 취급한다.
    Any 에는 toString, equals, hashCode 메소드가 정의되어 있다. 하지만 wait 이나 notify 등의 메소드는 사용할 수 없다. 그런 메소드를 호출하고 싶다면 java.lang.Object 타입으로 값을 캐스트해야 한다.

    Unit 타입

    Unit 타입은 자바의 void 와 같은 기능을 한다.
    Unit 은 모든 기능을 갖는 일반적인 타입이며 타입의 인자로 쓸 수 있다.
    Unit 타입의 인자는 Unit 하나 뿐이며 Unit 타입의 함수는 Unit 값을 묵시적으로 반환한다.
    이 두 특성은 제네릭 파라미터를 반환하는 함수를 오버라이드하면서 반환 타입으로 Unit 을 쓸 때 유용하다.

    interface Processor<T>{
        fun process() : T
    }
    
    class NoResultProvessor : Processor<Unit>{
        override fun process() {    //Unit을 반환하지만 반환 타입을 지정할 필요 없음
            // return을 명시할 필요가 없음
        }
    }

    Nothing 타입

    Nothing 타입은 아무 값도 포함하지 않는다. 따라서 함수의 반환 타입이나 반환 타입으로 쓰일 타입 파라미터로만 쓸 수 있다.

    fun fail(message: String) : Nothing {
        throw IllegalStateException(message)
    }

    Nothing 을 반환하는 함수를 엘비스 연산자의 우항에 사용해서 전제 조건을 검사할 수 있다.

    val address = company.address ?: fail("No address"
    println(address.city)

    참고 도서 - Kotlin in Action(2017)

    반응형

    댓글

Designed by Tistory.