본문으로 바로가기
반응형

이 글은 Kotlin In Action을 참고 하였습니다.

더욱 자세한 설명이나 예제는 직접 책을 구매하여 확인 하시기 바랍니다

코틀린은 원시타입과 wrapper type을 구분하지 않습니다.

즉 자바처럼 Integerint로 구분되지 않고 Int 하나만 존재합니다.

a : Int = 1
list : List<Int> = listof(1,2,3)
위 코드처럼 구분없이 사용하면 됩니다.

또한 type에 직접 메소드를 호출할 수 있습니다.
fun showProgress(progress: Int) {
    val percent = progress.coerceIn(0, 100)
    println("We're ${percent}% done!")
}

fun main(args: Array) {
    showProgress(146)
}

progress는 Int형이지만 바로 확장함수를 호출할 수 있습니다. coerceIn()은 범위를 한정하는 함수 입니다.


코틀린의 타입은 컴파일시 자바의 primitive 또는 wrapper 타입으로 자동변환됩니다.
Generic이나 Collection에서는 Integer로 변경되고 나머지 부분에서는 int로 변경됩니다

6.2.2 널 타입: Int?, Boolean?..

null이 가능한 코틀린 타입은 자바의 primitive type으로 변경이 불가 합니다. 따라서 wrapper type으로 변경됩니다.

data class Person(val name: String, val age: Int? = null) {

    fun isOlderThan(other: Person): Boolean? {
        if (age == null || other.age == null)
            return null
        return age > other.age
    }
}

fun main(args: Array) {
    println(Person("Sam", 35).isOlderThan(Person("Amy", 42)))
    println(Person("Sam", 35).isOlderThan(Person("Jane")))
}

age property의 경우 null이 될수 있으므로 컴파일되면 Integer type으로 바뀝니다.



6.2.3 숫자 변환

코틀린에서는 자동으로 숫자 type을 변환해 주지 않습니다.
즉 Int 값을 Long에 그냥 대입하면 compile error가 발생합니다.
따라서 Boolean을 제외한 원시타입은 toByte(), toShort(), toChar(), toLong(), toInt()..등 변환함수를 제공합니다.
 val i : Int = 0
val l : Long = i //컴파일 에러
val l : Long = i.toLong()

val list = listof(1L,2L,3L)
i in list // false
i.toLong() in list //true

숫자라도 비교를 위해서는 반드시 형변환을 하고 써야 합니다.

자바처럼 아래와 같은 literal을 지원합니다.
  • Long -> L : ex) 123L
  • Float -> F, f : ex) 1.23f 또는 432.54F
  • 16진수 -> 0x, 0X : ex) 0xFF, 0XFF
  • 2진수 -> 0B, 0b : ex) 0b0100, 0B00110011
문자열을 숫자로 변환할때도 "654".toInt() 같은 형태로 사용할 수 있습니다. (물론 실패시 NumberForamtException이 발생합니다.)

6.2.4 Any, Any? 최상위 타입

코틀린에는 Object 타입이 없는대신 이를 대신하는 Any, Any? type이 존재합니다.
기본적으로 Object 타입처럼 모든 객체의 상위객체라고 생각하면 됩니다.
(Any 타입은 컴파일시 Object로 변환됩니다.)
또한 이는 Int, Boolean등 원시타입의 상위객체이기도 합니다. (요건 자바와 다르네요)

Any 타입에는 null이 들어갈 수 없습니다. 따라서 null이 들어가야하는 곳에는 Any? 타입을 사용합니다.

자바의 java.lang.ObjecttoString(), equals(), hasCode() 이외에 wait(), notify()도 지원하지만 Any는 wait()와 notify()는 지원하지 않습니다.
따라서 wait()와 notify()를 사용해야 한다면 Any를 Object로 casting 한 후에 사용해야 합니다.

6.2.5 Unit type

Unit type은 자바의 void와 같은 역할을 합니다.
자바에서 void는 리턴값이 없음을 나타내는 keyword 처럼 쓰이지만 Unit type은 인자로도 사용할 수 있습니다.
inteface ShapeArea<T> {
    fun clac() : T
}

class NoResultProcessor : ShapeArea<Unit> {
    override fun clac() {
        println("36")
    }
}

Generic type으로 Unit을 지정하면 return을 명시적으로 넣지 안아도 됩니다.

만약 자바였다면 Void를 쓸수도 있습니다. (안드로이드의 AsyncTask의 기본 형태를 생각하면 됩니다.)

단 Void type이라도 return은 반드시 넣어야 하나 코틀린의 Unit은 return없이 사용 가능하다는 점이 다릅니다.


6.2.6 Nothing type

Nothing type은 함수가 정상적으로 끝나지 않는다라는걸 명시적으로 표현하는 함수입니다.
예를들어 중간에 throw 시키도록 한다면 해당 함수가 정상적으로 끝나지 않습니다.
이런 함수의 반환 type을 Nothing으로 두면 컴파일러가 정상종료가 되지 않는 함수임을 미리 알 수 있습니다.

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

fun main(args: Array) {
    fail("Error occurred")
}

Nothing은 return 타입이나 ,인자로만 쓸수 있습니다.

Nothing은 아무값도 저장할 수 없으므로 변수로 사용이 불가합니다.

fun getCompany(person: Person) {
    val comp = Person.company ?: fail("No company info.")
    return comp.name
}
위 코드에서 company 정보가 없다면 throw가 발생됩니다.

따라서 컴파일러는 comp.name 라인에서 null check 없이 값을 호출하도록 용인해 줍니다.


반응형