본문 바로가기

Kotlin/Reference

[Kotlin Reference] 기본 타입(Basic Types)


기본 타입(Basic Types)

코틀린에서 기본 타입들은 클래스로 정의되어 있습니다. 때문에 모든 변수에서 멤버 함수나 속성을 호출할 수 있습니다.



숫자(Numbers)


코틀린은 자바와 비슷하게 숫자를 처리하지만, 완전히 똑같지는 않습니다.


다음과 같은 숫자 표현을 제공합니다.


TypeBit width
Double64
Float32
Long64
Int32
Short16
Byte8

참고: 코틀린에서 character는 숫자가 아닙니다.

리터럴 상수(Literal Constants)

다음은 정수 값에 대한 리터럴의 종류입니다.


- 10진수:  123 

- Long은 대문자  L 을 붙입니다:  123L 

- 16진수:  0x0F 

- 바이너리:  0b00001011 


참고: 8진수는 지원하지 않습니다.


코틀린은 부동 소수점에 대한 표기법도 지원합니다.


- Double(기본값):  123.5 123.5e10 

- Float은  f  또는  F 를 붙입니다:  123.5f 

숫자 리터럴에서 밑줄 사용하기(Underscores in numeric literals, since 1.1)

밑줄을 사용하면 상수를 쉽게 읽을 수 있습니다:


1
2
3
4
5
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
cs

표현(Representation)

기본적으로 숫자는 JVM 기본 타입으로 저장됩니다.


하지만 숫자가 nullable( Int? )이거나 제네릭일 경우에는 객체화됩니다.


참고: 객체화된 숫자는 identity가 다릅니다.


1
2
3
4
5
6
7
fun main() {
    val a: Int = 10000
    println(a === a) // Prints 'true'
    val boxedA: Int= a
    val anotherBoxedA: Int= a
    println(boxedA === anotherBoxedA) // !!!Prints 'false'!!!
}
cs


하지만 그 값은 동일합니다:


1
2
3
4
5
6
7
fun main() {
    val a: Int = 10000
    println(a == a) // Prints 'true'
    val boxedA: Int= a
    val anotherBoxedA: Int= a
    println(boxedA == anotherBoxedA) // Prints 'true'
}
cs

명시적 변환(Explicit Conversions)

bit width가 작은 타입은 암시적인 변환으로는 큰 타입으로 변환할 수 없습니다.


1
2
3
4
// 가상의 코드, 실제로는 컴파일되지 않습니다:
val a: Int= 1 // 객체화된 Int (java.lang.Integer)
val b: Long= a // 암시적 변환으로 객체화된 Long 생성 (java.lang.Long)
print(b == a) // Long의 equals()로 체크하기 때문에 "false" 출력
cs


즉, 명시적인 변환 없이는  Int  변수에  Byte 타입의 값을 할당할 수 없습니다.


1
2
3
4
fun main() {
    val b: Byte = 1 // OK, 리터럴 상수가 정적으로 체크됩니다
    val i: Int = b // ERROR
}
cs


명시적 변환을 사용하여 확장된 숫자를 얻을 수 있습니다.


1
2
3
4
5
fun main() {
    val b: Byte = 1
    val i: Int = b.toInt() // OK: explicitly widened
    print(i)
}
cs


모든 숫자 타입은 다음과 같은 변환을 지원합니다.


-  toByte(): Byte 

-  toShort(): Short 

toInt(): Int 

toLong(): Long 

toFloat(): Float 

toDouble(): Double 

toChar(): Char 


문맥상에서 암시적 변환으로 타입이 유추되고, 적절한 변환을 위해 산술 연산이 오버로드됩니다. 예시:


1
val l = 1L + 3 // Long + Int => Long
cs

연산(Operations)

비트 단위 연산의 경우에는 특수 문자를 사용하지 않고, 정해진 이름의 중위함수를 사용합니다. 예시:


1
val x = (1 shl 2and 0x000FF000
cs


비트 연산의 전체 목록입니다.( Int 와  Long 만 사용 가능):


shl(bits)  – signed shift left (Java's  << )

shr(bits)  – signed shift right (Java's  >> )

ushr(bits)  – unsigned shift right (Java's  >>> )

and(bits)  – bitwise and

or(bits)  – bitwise or

xor(bits)  – bitwise xor

inv()  – bitwise inversion

부동 소수점 숫자 비교(Floating Point Numbers Comparison)

- 동등 체크:  a == b  a != b 

- 비교 연산:  a < b a > b a <= b a >= b 

- 범위 체크:  a..b x in a..b x !in a..b 


When the operands  and  are statically known to be  Float  or  Double  or their nullable counterparts (the type is declared or inferred or is a result of a smart cast), the operations on the numbers and the range that they form follow the IEEE 754 Standard for Floating-Point Arithmetic.


However, to support generic use cases and provide total ordering, when the operands are not statically typed as floating point numbers (e.g.  Any Comparable<...> , a type parameter), the operations use the  equals  and  compareTo  implementations for  Floa and  Double , which disagree with the standard, so that:


NaN  is considered equal to itself

NaN  is considered greater than any other element including  POSITIVE_INFINITY 

-0.0  is considered less than  0.0 



문자(Characters)


Characters are represented by the type  Char . They can not be treated directly as numbers


1
2
3
4
5
fun check(c: Char) {
    if (c == 1) { // ERROR: incompatible types
        // ...
    }
}
cs


Character literals go in single quotes:  '1' . Special characters can be escaped using a backslash. The following escape sequences are supported:  \t \b \n \r \' \" \\  and  \$ . To encode any other character, use the Unicode escape sequence syntax:  '\uFF00' .


We can explicitly convert a character to an  Int  number:


1
2
3
4
5
fun decimalDigitValue(c: Char): Int {
    if (c !in '0'..'9')
        throw IllegalArgumentException("Out of range")
    return c.toInt() - '0'.toInt() // Explicit conversions to numbers
}
cs


Like numbers, characters are boxed when a nullable reference is needed. Identity is not preserved by the boxing operation.



불리언(Booleans)


The type  Boolean  represents booleans, and has two values: true and false.


Booleans are boxed if a nullable reference is needed.


Built-in operations on booleans include


||  – lazy disjunction

&&  – lazy conjunction

- negation



배열(Arrays)


Arrays in Kotlin are represented by the  Array  class, that has  get  and  set  functions (that turn into  []  by operator overloading conventions), and  size  property, along with a few other useful member functions:


1
2
3
4
5
6
7
8
class Array<T> private constructor() {
    val size: Int
    operator fun get(index: Int): T
    operator fun set(index: Int, value: T): Unit

    operator fun iterator(): Iterator<T>
    // ...
}
cs


To create an array, we can use a library function  arrayOf()  and pass the item values to it, so that  arrayOf(1, 2, 3)  creates an array  [1, 2, 3] . Alternatively, the  arrayOfNulls()  library function can be used to create an array of a given size filled with null elements.


Another option is to use the  Array  constructor that takes the array size and the function that can return the initial value of each array element given its index:


1
2
3
4
5
fun main() {
    // Creates an Array<String> with values ["0", "1", "4", "9", "16"]
    val asc = Array(5) { i -> (i * i).toString() }
    asc.forEach { println(it) }
}
cs


As we said above, the  []  operation stands for calls to member functions  get()  and  set() .


Note: unlike Java, arrays in Kotlin are invariant. This means that Kotlin does not let us assign an  Array<String>  to an  Array<Any> , which prevents a possible runtime failure (but you can use  Array<out Any> , see Type Projections).


Kotlin also has specialized classes to represent arrays of primitive types without boxing overhead:  ByteArray ShortArray IntArray  and so on. These classes have no inheritance relation to the  Array  class, but they have the same set of methods and properties. Each of them also has a corresponding factory function:


1
2
val x: IntArray = intArrayOf(123)
x[0= x[1+ x[2]
cs



부호 없는 정수(Unsigned integers)


Unsigned types are available only since Kotlin 1.3 and currently are experimental. See details below


Kotlin introduces following types for unsigned integers:


kotlin.UByte : an unsigned 8-bit integer, ranges from 0 to 255

kotlin.UShort : an unsigned 16-bit integer, ranges from 0 to 65535

kotlin.UInt : an unsigned 32-bit integer, ranges from 0 to 2^32 - 1

kotlin.ULong : an unsigned 64-bit integer, ranges from 0 to 2^64 - 1


Unsigned types support most of the operations of their signed counterparts.


Note that changing type from unsigned type to signed counterpart (and vice versa) is a binary incompatible change


Unsigned types are implemented using another experimental feature, namely inline classes.

특화된 클래스(Specialized classes)

Same as for primitives, each of unsigned type has corresponding type that represents array, specialized for that unsigned type:


kotlin.UByteArray : an array of unsigned bytes

kotlin.UShortArray : an array of unsigned shorts

 kotlin.UIntArray : an array of unsigned ints

kotlin.ULongArray : an array of unsigned longs


Same as for signed integer arrays, they provide similar API to  Array  class without boxing overhead.


Also, ranges and progressions supported for  UInt  and  ULong  by classes  kotlin.ranges.UIntRange kotlin.ranges.UIntProgression kotlin.ranges.ULongRange kotlin.ranges.ULongProgression 

리터럴(Literals)

To make unsigned integers easier to use, Kotlin provides an ability to tag an integer literal with a suffix indicating a specific unsigned type (similarly to Float/Long):


- suffixes  and  tag literal as unsigned. Exact type will be determined based on the expected type. If no expected type is provided,  UInt  or  ULong  will be chosen based on the size of literal


1
2
3
4
5
6
val b: UByte = 1u  // UByte, expected type provided
val s: UShort = 1u // UShort, expected type provided
val l: ULong = 1u  // ULong, expected type provided

val a1 = 42u // UInt: no expected type provided, constant fits in UInt
val a2 = 0xFFFF_FFFF_FFFFu // ULong: no expected type provided, constant doesn't fit in UInt
cs


- suffixes  uL  and  UL  explicitly tag literal as unsigned long.


1
val a = 1UL // ULong, even though no expected type provided and constant fits into UInt
cs

부호 없는 정수의 실험적 상태(Experimental status of unsigned integers)

The design of unsigned types is experimental, meaning that this feature is moving fast and no compatibility guarantees are given. When using unsigned arithmetics in Kotlin 1.3+, warning will be reported, indicating that this feature is experimental. To remove warning, you have to opt-in for experimental usage of unsigned types.


There are two possible ways to opt-in for unsigned types: with marking your API as experimental too, or without doing that.


- to propagate experimentality, either annotate declarations which use unsigned integers with  @ExperimentalUnsignedTypes  or pass  -Xexperimental=kotlin.ExperimentalUnsignedTypes  to the compiler (note that the latter will make all declaration in compiled module experimental)

- to opt-in without propagating experimentality, either annotate declarations with  @UseExperimental(ExperimentalUnsignedTypes::class)  or pass  -Xuse-experimental=kotlin.ExperimentalUnsignedTypes 


It's up to you to decide if your clients have to explicitly opt-in into usage of your API, but bear in mind that unsigned types are an experimental feature, so API which uses them can be suddenly broken due to changes in language.


See also or Experimental API KEEP for technical details.



문자열(Strings)


Strings are represented by the type  String . Strings are immutable. Elements of a string are characters that can be accessed by the indexing operation:  s[i] . A string can be iterated over with a for-loop:


1
2
3
4
5
6
fun main() {
val str = "abcd"
    for (c in str) {
        println(c)
    }
}
cs


You can concatenate strings using the  operator. This also works for concatenating strings with values of other types, as long as the first element in the expression is a string:


1
2
3
4
fun main() {
    val s = "abc" + 1
    println(s + "def")
}
cs


Note that in most cases using string templates or raw strings is preferable to string concatenation.

문자열 리터럴(String Literals)

Kotlin has two types of string literals: escaped strings that may have escaped characters in them and raw strings that can contain newlines and arbitrary text. An escaped string is very much like a Java string:


1
val s = "Hello, world!\n"
cs


Escaping is done in the conventional way, with a backslash. See Characters above for the list of supported escape sequences.


A raw string is delimited by a triple quote ( """ ), contains no escaping and can contain newlines and any other characters:


1
2
3
4
val text = """
    for (c in "foo")
        print(c)
"""
cs


You can remove leading whitespace with trimMargin() function:


1
2
3
4
5
6
val text = """
    |Tell me and I forget.
    |Teach me and I remember.
    |Involve me and I learn.
    |(Benjamin Franklin)
    """.trimMargin()
cs


By default  is used as margin prefix, but you can choose another character and pass it as a parameter, like  trimMargin(">") .

문자열 템플릿(String Templates)

String literals may contain template expressions, i.e. pieces of code that are evaluated and whose results are concatenated into the string. A template expression starts with a dollar sign ($) and consists of either a simple name:


1
2
3
4
fun main() {
    val i = 10
    println("i = $i"// prints "i = 10"
}
cs


or an arbitrary expression in curly braces:


1
2
3
4
fun main() {
    val s = "abc"
    println("$s.length is ${s.length}"// prints "abc.length is 3"
}
cs


Templates are supported both inside raw strings and inside escaped strings. If you need to represent a literal  character in a raw string (which doesn't support backslash escaping), you can use the following syntax:


1
2
3
val price = """
${'$'}9.99
"""
cs




출처


https://kotlinlang.org/docs/reference/basic-types.html



'Kotlin > Reference' 카테고리의 다른 글

[Kotlin Reference] 기본 문법(Basic Syntax)  (0) 2019.06.16