CharArray란?
CharArray는 원시 타입 Char으로 이루어진 배열을 나타낸다.
/**
* ...
* On the JVM, non-nullable values of this type are represented as values of the primitive type `char`.
*/
public class Char private constructor() : Comparable<Char>
Char 클래스의 주석에 따르면 Kotlin은 non-nullable한 Char을 JVM상에서 Java의 원시 타입인 char과 똑같이 저장한다. 이러한 non-nullable한 Char 값들의 집합을 원시 타입을 유지하면서 배열로 만든 것이 바로 CharArray이다.
CharArray는 언뜻 보면 Array<Char>과 비슷해 보이지만, Array 클래스는 원시 타입이 아닌 참조 타입 변수만을 인자로 받으므로 Array<Char> 속에 들어간 Char은 Char이 한 번 감싸진 객체이다. 즉, CharArray의 Char은 Java의 char과 대응되고, Array<Char>의 Char은 Java의 Character과 대응된다.
Kotlin은 개발자의 편의성을 위해 이런 부분들을 모두 컴파일러단에서 처리하며, 개발자는 이에 대한 것을 몰라도 코드를 짤 수 있다. 이에 대한 것은 CharArray의 주석에 나와있다 아래 Kotlin CharArray class의 주석을 살펴보자.
/**
* An array of chars. When targeting the JVM, instances of this class are represented as `char[]`.
* ...
*/
public class CharArray(size: Int)
char의 배열. JVM에서 실행될 때 이 클래스의 인스턴스는 char[] 으로 표현된다.
위 주석을 직역해보면 CharArray는 JVM에서 돌아갈 때, char[]로 표현된다고 나와있는 것을 볼 수 있다.
자 이제 CharArray가 무엇인지는 간단히 살펴봤으니 어떻게 조작할 수 있는지 살펴보도록 하자.
CharArray조작하기
CharArray 생성하기
CharArray를 생성하는 방법은 세가지가 있다. CharArray 생성자를 사용해 초기값을 설정하지 않고 초기화 하는 방법, CharArray 생성자를 사용해 초기값을 설정해 초기화 하는 방법, charArrayOf를 사용해 초기화 하는 방법이다.
CharArray 생성자를 사용해 초기값을 설정하지 않고 초기화 하는 방법
/**
* @constructor Creates a new array of the specified [size], with all elements initialized to null char (`\u0000').
*/
public class CharArray(size: Int) {
CharArray 생성자를 사용해 초기값을 설정하지 않고 초기화 하기 위해서는 CharArray에 CharArray 크기만 넘기면 된다. 그러면 CharArray는 기본 값인 \u0000으로 설정된다고 나와있다. \u0000은 ASCII 코드표에서 'null 문자'를 나타낸다. 하지만, 아까 이야기 했듯이 CharArray는 Non-nullable한 문자의 집합이다. 그런데 'null 문자'라니 무슨 말일까?
이는 JVM의 null과 'Null' 문자는 달라서 그렇다. JVM의 null은 말 그대로 참조가 없는 값이고 'null 문자'는 실제 값은 있는데 문자 이름이 null일 뿐이다.
*Kotlin은 UTF-16인코딩을 사용하고 있고, UTF-16(\u0000)은 ASCII의 0번 문자에 대응되는데 0번 문자는 null이다.
이를 확인하기 위해 CharArray는 아래와 같이 생성해 출력해보자
fun main() {
val createdArray = CharArray(3)
println("index 0 value >> ${createdArray[0]}")
println("index 1 value >> ${createdArray[1]}")
}
Char Array 출력 결과에 NUL이라는 문자가 조그맣게 표시되는 것을 확인할 수 있다.
만약 실제 null을 출력하면 다음과 같이 문자로 null이라고 나온다.
fun main() {
println("null value >> ${null}")
}
CharArray 생성자를 사용해 초기값을 설정해 초기화 하는 방법
CharArray(size: Int, init: (Int) -> Char) 을 사용해 size크기의 CharArray를 생성할 수 있다.
public class CharArray(size: Int) {
public inline constructor(size: Int, init: (Int) -> Char)
}
ASCII 65번이 'A'이므로 아래와 같이 출력하면 0번 인자는 A 1번 인자는 B가 출력된다.
fun main() {
val createdArray = CharArray(3) {
Char(it + 65)
}
println("index 0 value >> ${createdArray[0]}")
println("index 1 value >> ${createdArray[1]}")
}
index 0 value >> A
index 1 value >> B
charArrayOf를 사용해 초기화하는 방법
charArrayOf를 사용해 초기화 하려면 Char 값을 argument 목록으로 넘기기만 하면된다.
/**
* Returns an array containing the specified characters.
*/
public fun charArrayOf(vararg elements: Char): CharArray
아래와 같이 A, B, C를 넘기면 순서대로 Array가 만들어지는 것을 볼 수 있다.
fun main() {
val createdArray = charArrayOf('A','B','C')
println("index 0 value >> ${createdArray[0]}")
println("index 1 value >> ${createdArray[1]}")
}
index 0 value >> A
index 1 value >> B
CharArray로 String 만들기
문자열의 배열인 CharArray는 String의 생성자로 넘어가면 String으로 바뀐다.
@kotlin.internal.InlineOnly
public actual inline fun String(chars: CharArray): String =
java.lang.String(chars) as String
즉, 아래와 같이 실행하면 "ABC" String이 만들어진다.
val createdArray = charArrayOf('A','B','C')
val createdString = String(createdArray)
println(createdString)
ABC
String 저장 시 CharArray의 메모리 공간 차지 방식
이 메서드는 String은 CharArray를 바이트로 저장하기 때문에 새로운 공간을 차지하는 것을 기본으로 한다.
...
public String(char value[]) {
this(value, 0, value.length, null);
}
...
String(char[] value, int off, int len, Void sig) {
...
this.coder = UTF16;
this.value = StringUTF16.toBytes(value, off, len);
}
...
정리하며
이번 글에서는 Char Primitive Type 값으로 이루어진 CharArray를 만드는 방법에 대해 살펴봤다. CharArray를 만드는 방법과 내부 값이 어떻게 초기화 되는지에 대해 제대로 알고 가도록 하자.