어떤 변수에 대해 멤버함수와 프로퍼티를 호출할 수 있습니다. 그렇기에 코틀린의 모든것은 클래스로 이루어져 있습니다.
코틀린에서 정수형과 실수형을 모두 Numbers클래스를 상속받아 구현됩니다.
이 Numbers 클래스는 추상 클래스로 toInt, toFloat 등 다양한 형변환 함수들을 추상 멤버 함수로 갖고 있습니다.
따라서 이를 상속받은 각 정수형, 실수형 클래스에서 이를 구현합니다.
정수형은 Int의 범위를 벗어나지 않는 값에 대해서 타입을 지정하지 않으면 기본으로 Int로 타입 추론됩니다.
Int의 범위를 넘어서는 값은 자동으로 Long으로 타입추론 됩니다.
또한 숫자 뒤에 명시적으로 L을 붙여서 자료형이 Long임을 나타낼수도 있습니다.
val num1 = 10 // Int
val num2 = -124 // Int
val num3 = 123L // Long
val num4 = 3000000000 // Long
val num5: Short = 3000 // Short
val num6: Byte = 100 // Byte
실수형은 변수에 타입을 지정하지 않으면 기본적으로 타입추론 됩니다.
실수값 뒤에 명시적으로 f 또는 F를 붙여서 자료형이 Float임을 나타낼수도 있습니다.
val realNum1 = 1.0 // Double
val realNum2 = 1.0f // Float
val realNum3: Double = 1 // Compile Error
코틀린은 다른 언어들과는 서로 다른 숫자 타입을 대입하는 경우에 암시적 형변환을 허용하지 않습니다. 예를 들어, Int형의 변수를 Long형의 변수에 대입할 수 없습니다.(명시적으로 형변환을 하지 않는다면)
var num: Int = 3
val longNum: Long = 5
num = longNum // Compile Error
num = longNum.toInt // Success
숫자값의 가독성을 높이기 위해 밑줄을 사용할 수 있습니다.
val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010
코틀린은 자바와 완전히 호환되는 언어입니다. 숫자 타입에 대해서도 코틀린과 자바는 완전히 호환됩니다.
코틀린의 숫자 타입은 자바의 기본형과 참조형을 모두 나타낼 수 있습니다.
기본적으로 숫자 타입은 기본형입니다. 하지만 Nullable타입을 사용하거나 Collection에 요소로 사용되면 참조형으로 변환됩니다.
val num: Int = 3 // num is int
val num2: Int? = 3 // num2 is Integer
val l1 = listOf(num) // num is Integer
위에서 알아봤듯이, 코틀린은 서로 다른 타입에서 대입연산을 할 때, 암시적 형변환을 지원하지 않는다. 따라서 서로 다른 숫자 타입끼리 대입하기 위해서는 명시적 형변환을 통해 자료형을 같게 만들어 주어야한다.
val num = 5
var num2: Long
num2 = num // Compile Error
num2 = num.toLong()
코틀린은 숫자에 대한 수학적 연산자를 제공합니다. +, -, *, /, %가 제공됩니다. 이러한 연산자들은 적절한 클래스의 멤버 메소드로써 선언됩니다.
각 연산자에 해당하는 메소드
서로 다른 타입끼리 연산을 하면 그 결과는 더 크기가 큰 타입이 된다.
val num = 5
val num2 = 5.0
println(num / num2)
// [출력]
// 1.0
코틀린은 정수형에 대한 비트연산을 제공합니다. 비트연산은 함수로 제공되는데 이러한 연산은 중위형식으로 사용될 수 있습니다. 이러한 비트연산은 오직 Int와 Long형에만 적용될 수 있습니다.
val num = 2
println(num.shl(2)) // 일반적인 함수 표현
println(num shl 2) // 중위 형식 표현
// [출력]
// 8
// 8
Characters는 Char로 표현된다. Char형식의 값은 작은 따옴표로 감싸서 표현한다. (ex. val c: Char = 'a')
문자 변수의 값이 숫자인 경우 digitToInt() 함수를 사용하여 명시적으로 Int 숫자로 변환할 수 있습니다.
val c: Char = 'a' // Char
val c2: Char? = 'a' // Character
val c3 = '5' // Char
val num: Int = c3.digitToInt() // Int
문자열은 코틀린에서 String으로 표현됩니다. 일반적으로, String의 값은 쌍따옴표(")안에 문자의 연속으로 사용합니다.
val str: String = "abcde"
String 내의 문자는 str[i]처럼 인덱스로 접근할 수 있습니다. 또한 for 반복문을 사용하여 문자열 내의 문자를 순회할 수도 있습니다.
val str: String = "abcde"
println(str[2]) // 출력: c
for (c in str)
print(c) // 출력: abcde
String은 변경할 수 없습니다. 문자열을 초기화하면 값을 변경할 수 없습니다. String은을 변환하는 모든 작업은 결과를 새 String 객체에 반환하고 원래 String은 변경되지 않은 상태로 유지합니다.
val str: String = "abcde"
println(str.uppercase()) // 출력: "ABCDE"
println(str) // 출력: "abcde"
String은 다른 String을 이어붙이기 위해 '+'연산을 제공합니다. 이런 '+' 연산은 다른 자료형을 붙이는데에도 사용될 수 있습니다.
val str: String = "abcde" + 1
println(str) // 출력: abcde1
println(str + "fghi") // 출력: abcde1fghi
원시 문자열은 삼중 따옴표로 구분 됩니다. 원시 문자열은 기존의 문자열과 달리 이스케이프를 포함하지 않으며, 개행과 기타 문자를 포함할 수 있습니다.
val text = """
"abc"'cde'
"abbbbb"
""".trimIndent() // indent를 무시함.
print(text)
String은 String Template을 포함할 수 있습니다. 템플릿 표현식은 달러 기호($)로 시작하고 다음과 같이 사용될 수 있습니다.
val num = 42
println("num is $num") // 출력: num is 42
val word = "abcde"
println("$word.length is ${word.length}") // 출력: abcde.length is 5
Kotlin의 배열은 Array 클래스로 표현됩니다. Array클래스는 get 과 set연산자 오버로딩 함수를 가지고 있습니다. 이러한 함수는 [index] 표현을 통해 해당 인덱스의 요소에 접근하게 해줍니다.
배열을 생성하려면 arrayOf() 함수를 사용하고 각 요소의 값을 배열에 전달하여 생성합니다. 예를 들어, arrayOf(1, 2, 3)은 배열 [1, 2, 3]을 생성합니다. 또는 arrayOfNulls() 함수를 사용하여 null 요소로 채워진 지정된 크기의 배열을 만들 수 있습니다.
val arr = arrayOf(1, 2, 3, 4, 5)
arr[3] = 3 // this is set
println(arr[3]) // this is get
println(arr.contentToString()) // 출력: [1, 2, 3, 3, 5]
또 다른 방법은 배열 크기를 인자로 받는 Array 생성자와 인덱스가 지정된 배열 요소의 값을 반환하는 함수를 사용하는 것입니다.
val arr = Array(5) { it + 1 }
println(arr.contentToString()) // 출력: [1, 2, 3, 4, 5]
Kotlin에는 ByteArray, ShortArray, IntArray 등 boxing 오버헤드 없이 기본 유형의 배열을 나타내는 클래스도 있습니다. 이러한 클래스는 Array 클래스와 상속 관계가 없지만 메소드 및 프로퍼티의 집합이 Array와 동일합니다.