기본 타입
숫자
자바와 유사하지만 완전히 같지는 않다 / 숫자에 대해 넓은 타입으로의 자동 변환 없음 / 리터럴도 다를수 있음
- 숫자 내장 타입(자바와 비슷)
타입 비트크기
Double 64
Float 32
Long 64
Int 32
Short 16
Byte 8
코틀린에서 문자는 숫자가 아니다
리터럴 상수
정수 값을 위한 리터럴 상수 종류
- 십진수 : 123 / Long은 대문자 L 표시 : 123L
- 16진수 : 0x0F
- 2진수 : 0b00001011
주의 : 8진수 리터럴은 지원하지 않음
부동소수점 표기 - 기본은 Double : 123.5, 123,5e10
- Float는 f나 F 표시 : 123.5f
숫자 리터럴에 밑줄
숫자 상수의 가독성을 높이기 위해 밑줄 사용 가능
val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
표현
자바 플랫폼에서는 JVM 기본 타입으로 숫자 저장 / 만약 null가능 숫자 레퍼런스(Int?)가 필요하거나 지네릭이 관여하면 박싱 타입으로 저장
숫자를 박싱하면 동일성이 유효하지 않음
- == : 타입과 상관없이 비교
- === : 타입까지
val a: Int = 10000
print(a === a) // 'true' 출력
val boxedA: Int? = a
val anotherBoxedA: Int? = a
print(boxedA === anotherBoxedA) // 'false' 출력
하지만 값의 동등함은 유지
val a: Int = 10000
print(a === a) // 'true' 출력
val boxedA: Int? = a
val anotherBoxedA: Int? = a
print(boxedA == anotherBoxedA) // 'true' 출력
명시적 변환
표현이 다르므로 작은 타입이 큰 타입의 하위 타입은 아님
val a: Int? = 1 // 박싱된 Int
val b: Long? = a // 자동 변환은 박싱된 Long 생성
print(a == b) // 'false' 리턴 왜냐면 Long의 equals()는 비교 대상도 Long인지 검사
이런 이유로 작은 타입을 큰 타입으로 자동으로 변환하지 않는다. 이는 명시적 변환없이 Byte 타입 값을 Int 변수에 할당할 수 없음을 뜻함
val b: Byte = 1 // OK, 리터럴은 정적으로 검사
val a: Int = b // ERROR
명시적으로 숫자를 넓히는 변환할 수 있다
val i: Int = b.toInt() // OK, 명시적으로 넓힘
모든 숫자 타입은 다음 변환을 지원
- toByte()
- toShort()
- toInt()
- toLong()
- toFloat()
- toDouble()
- toChar()
자동 변환의 부재를 거의 느낄 수 없는데 이유는 타입을 컨텍스트에서 추론하고 수치 연산을 변환에 알맞게 오버로딩했기 때문이다
val l = 1L + 3 // Long + Int => Long
연산
비트 연산자를 위한 특수 문자는 없고 중의 형식으로 호출할 수 있는 함수 제공
val x = (1 sh1 2) and 0x000FF000
비트 연산자 목록
- shl(bits) : 부호있는 왼쪽 시프트(자바의 «)
- shr(bits) : 부호있는 오른쪽 시프트(자바의 »)
- ushr(bits) : 부호없는 오른쪽 시프트(자바의 »>)
- and(bits) : 비트 AND
- or(bits) : 비트 OR
- xor(bits) : 비트 XOR
- inv() : 비트 역
부동소수 비교
- 동듭함 비교 : a == b, a != b
- 비교 연산자 : a > b, a < b, a >= b, a <= b
- 범위 생성과 검사 : a..b, x in a..b, x != a..b
문자
Char타입으로 문자를 표현 / 이 타입을 바로 숫자로 다룰 수 없다
fun check(c: Char) {
if (c == 1) { // ERROR: 비호환 타입
// ...
}
}
문자 리터럴은 작은 따옴표 안에 표시 ‘1’
문자를 Int 숫자로 명시적으로 변환할 수 있다
fun decimalDigitValue(c: Char) : Int {
if(c !in '0'..'9')
throw IllegalArgumentException("Out of range")
return c.toInt() - '0'.toInt() // 숫자로 명시적 변환
}
숫자와 마찬가지로 문자도 null 가능 레퍼런스가 필요하면 박싱됨 / 박싱 연산을 하면 동일성은 유지되지 않음
불리언
Boolean 타입은 불리언을 표현하고 두 값이 존재 (true, false)
null 가능 레퍼런스가 필요하면 불리언도 박싱
-
: 지연 논리합 - && : 지연 논리곱
- ! : 역
배열
Array 클래스로 배열 표현 / 이 클래스는 get과 set함수, size프로퍼티와 그외 유용한 멤버 함수 제공
라이브러리 함수 ArrayOf()를 사용하여 배열 생성 — arrayOf(1, 2, 3)은 [1,2,3] 배열 생성
arrayOfNulls() 라이브러리 함수를 사용하면 주어진 크기의 null로 채운 배열 생성
ByteArray, ShortArray, IntArray등 기본 타입의 배열을 표현하기 위한 특수 클래스 제공
val x : IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
문자열
문자열은 String타입으로 표현 / 문자열은 불변 / 문자열의 요소는 s[i]와 같은 인덱스 연산으로 접근 가능 / for로프로 순회도 가능
for(c in str)
print(c)
문자열 리터럴
두 가지 타입의 문자열 리터럴 지원
- escaped문자열 : 탈출 문자 가질 수 있다(자바 문자열과 거의 같다)
- raw문자열 : 뉴라인과 임의 텍스트를 가질 수 있다
val s = "Hello, World!\n" /// escaped
raw문자열은 세 개의 따움표로 구분 / 특수 문자를 포함하지 않고 뉴라인과 모든 다른 문자 포함 가능
val text =
"""
for(c in "foo")
print(c)
"""
trimMargin()함수를 사용해서 양쪽 공백 제거 가능
val text =
"""
|Tell me,
|Teach me
""".trimMargin()
문자열 템플릿
문자열은 템플릿 식을 포함할 수 있다 / 코드 조각을 계산하고 그 결과를 문자열에 넣을 수 있다 / 템플릿 식은 $부호로 시작
val i = 10
val s = "i = $i" // "i = 10" 출력
중괄호 안에 임의의 식을 넣을 수 있다
val s = "abc"
val str = "$s.length is ${s.length}" // "abc.length is 3" 출력
raw문자열과 escaped문자열 안에 템플릿을 넣을 수 있다