Kotlin (코틀린)

[Kotlin] 코틀린 자료형 / 타입 캐스팅 / 값 비교

Oscar:) 2024. 5. 6. 20:00

 

 

이번 포스팅에서는 코틀린의 자료형에 대해 알아보자.

 

 


 

자료형

 

 

코틀린에서는 자료형을 원시 타입과 참조 타입으로 구분하지 않는다.

모든 자료형은 참조 타입으로 통일되었다.

 

 

타입 키워드
정수형 Byte
Short
Int
Long
실수형 Float
Double
논리형 Boolean
문자형 Char
문자열 String

 

 

원시 타입과 참조 타입에 대한 자세한 내용은 다음 포스팅에서 다뤄보겠다.

지금은 단순히, 원시 타입이 아니기에 첫 글자를 대문자로 작성하는구나..! 정도만 알고 넘어가도 된다.

 

 


 

 

 

이 밖에도 Any 라는 자료형이 존재하는데,

이는 코틀린 내 모든 자료형의 조상 격이라고 볼 수 있다.

 

따라서 모든 자료형을 대체할 수 있는데,

간단한 예시와 함께 보자.

 

 

Int와 String을 사용한 간단한 출력문이다.

val age: Int = 29
val name: String = "Oscar"

println("${name}는 ${age}살")

// 출력 : Oscar는 29살

 

 

이를 Any로 대체한다면

val age: Any = 29
val name: Any = "Oscar"

println("${name}는 ${age}살")

// 출력 : Oscar는 29살

 

위 처럼 동일한 기능을 수행할 수 있다.

 

 

사실, 위 처럼 모든 자료형을 Any로 명시하려고 사용하지는 않는다.

여러 자료형을 혼합해서 사용하는 자료구조에서 유용하게 사용할 수 있다.

 

 

 


 

타입 추론

 

 

코틀린은 기본적으로 타입 추론을 지원한다.

var age = 29
var name = "Oscar"

 

따라서 위와 같이 코드를 작성하여도

age는 Int 자료형, name은 String 자료형이라는 것을 인식한다.

 

적응하면 할수록 정말 편리한 기능이 아닐 수 없다고 느낀다.

 

 

반면, 타입을 명시해 줄 때는 다음과 같이 작성한다.

var age : Int = 29
var name : String = "Oscar"

 

 


 

 

✅ 어차피 자동으로 타입 추론되는데 굳이 왜 명시함?

 

타입 추론은 어디까지나 편의에 가까운 기능이라고 생각해야 한다.

 

타입 추론에 대한 결과를 모든 상황에서 완벽하게 신뢰할 수 없을 수 있고,

개발자가 어떤 의도를 갖고 코드를 작성하는지에 따라 사용하지 않을 수도 있기 때문이다.

 

 

정말 간단한 예시로, Int 자료형과 Byte 자료형을 구분해보자.

 

 

위와 같이, 변수에 타입을 작성하지 않았다면 29라는 정수는 무조건 Int로 추론한다.

 

하지만 Int는 4byte의 메모리 용량을 차지하고, Byte는 1byte만 차지하기 때문에

개발자는 Byte 자료형을 사용하고 싶을 수도 있는 것이다.

 

 

 

위와 같이 자료형을 명시해주면 29라는 정수도 Byte로 컴파일된다.

 

위는 정말 단순한 예시일 뿐이고, 이외에도 작업을 하다보면

타입을 명시해야만 하는 상황을 맞이하게 될 것이다.

 

 

 


 

타입 캐스팅 (형 변환)

 

 

코틀린에서는 .to자료형() 문법으로 손쉽게 타입 캐스팅할 수 있다. 

 

val age = 100

println(age.toByte())
println(age.toShort())
println(age.toLong())
println(age.toFloat())
println(age.toDouble())
println(age.toChar())
println(age.toString())

 

결과)

 

위 처럼, 대부분의 자료형은 자유롭게 캐스팅할 수 있다.

 

기존의 자바와 비교하자면,

Integer.parseInt() 등 래퍼 클래스를 이용해 번거롭게 캐스팅하지 않아도 된다.

 

 

 


 

값 비교

 

 

값 비교에 대해서는 별 것도 아닌 내용이라 생각할 수 있지만,

유심히 볼만한 내용이 있으니 꼭 읽었으면 좋겠다.

 

 

간단한 다음 예제를 보자.

val i = 10
val j = 10

print(i == j)

// 결과 : true

 

위 코드에서 이상한 점을 찾아볼 수 있는가?

 

i와 j는 정수형 자료형이기에 (==) 연산자로 비교하는 것이 이상하지 않을 것이다.

 

하지만 코틀린에서 Int 타입은 참조 타입이라는 것을 잊으면 안된다.

 

 

기존 자바에서 참조 타입 [ex)String] 을 비교할 때

equals() 메서드를 사용하지 않았는가?

 

 

 

이제 다음 예제를 보자.

val str1 = "Oscar"
val str2 = "Oscar"

print(str1 == str2)

// 결과 : true

 

이제서야 조금 이상하다고 보일 수도 있다.

String 값을 (==) 연산자로 비교했기 때문이다.

 

 

다시 언급하지만, 코틀린에서는 모든 자료형을 참조 타입으로 통일했다.

 

그렇다면 모든 자료형을 비교할 때 equals() 메서드를 사용했어야 하지만,

(==) 연산자로 비교하는 방식을 채택했다.

 

 

사실 이는 개발자에게 편의를 제공해 줄 뿐,

(==) 연산자는 내부적으로 equals() 메서드를 호출하여 동작한다.

 

코틀린 이 녀석... 어디까지 개발자 입장을 고려해주는거냐...

 

 

 

(==) 연산자참조 타입의 실제 값 비교를 해주며,

참조 타입 객체의 주소 값을 비교하려면 (===) 연산자를 사용하면 된다.

 

 

 


 

 

 

 

'코틀린은 간결하다' 라는 말을 단순히 간결한게 끝이라고 보면 안 된다.

그 간결함은 개발자들에게 편의를 제공하기 위해 포장된 노력이 만든 것 같다고 느낀다.

 

코틀린은 쳐다보면 볼수록 감동적인 언어다...