코틀린에서 배열을 출력해보면 다음과 같이 나타난다.
이는 println을 깊게 파고 들어가면 알 수 있는데
//코틀린에서 내가 호출한 함수
@kotlin.internal.InlineOnly
public actual inline fun println(message: Any?) {
//내부적으로 호출되는 자바프린트 함수
System.out.println(message)
}
//내부적으로 호출되는 자바프린트 함수의 구현
public void println(Object x) {
//오브젝트를 문자열로 변환
String s = String.valueOf(x);
synchronized (this) {
//변환된 문자열 출력
print(s);
//개행
newLine();
}
}
//프린트 함수 내부 valuOf 함수 구현
public static String valueOf(Object obj) {
//오브젝트가 null 이면 null
//null이 아니면 toString()
return (obj == null) ? "null" : obj.toString();
}
//Object클래스의 toString() 함수 구현
public String toString() {
//오브젝트의 클래스이름을 얻어서 @ 문자열과 해쉬코드를 16진수로 변환한 문자열 조합한 문자열을 반환
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
코틀린에서 자바에서 Object에 해당하는 Any를 출력하는 부분에서 타고 들어가면 위의 과정을 거친다.
더 깊은 과정은 생략 하도록 하겠다.
결국 내가 프린트한 값은 오브젝트의 클래스네임 과 오브젝트의 해쉬코드를 16진수 스트링으로 변경하여 나타내는 문자열이다.
여기서 joinToString() 을 사용하면 간편하게 출력을 할 수 가 있다.
내부코드를 들여다 보자
public fun IntArray.joinToString(
separator: CharSequence = ", ",
prefix: CharSequence = "",
postfix: CharSequence = "",
limit: Int = -1,
truncated: CharSequence = "...",
transform: ((Int) -> CharSequence)? = null
): String {
return joinTo(
StringBuilder(),
separator,
prefix,
postfix,
limit,
truncated,
transform
).toString()
}
joinToString 함수는 내부적으로 joinTo 함수를 호출하여 반환된 문자열을 보여준다. 다른 유형의 joinToString 함수도 위와 같이 구현되어있다.
public fun <A : Appendable> IntArray.joinTo(
buffer: A,
separator: CharSequence = ", ",
prefix: CharSequence = "",
postfix: CharSequence = "",
limit: Int = -1,
truncated: CharSequence = "...",
transform: ((Int) -> CharSequence)? = null
): A {
buffer.append(prefix)
var count = 0
for (element in this) {
if (++count > 1) buffer.append(separator)
if (limit < 0 || count <= limit) {
if (transform != null)
buffer.append(transform(element))
else
buffer.append(element.toString())
} else break
}
if (limit >= 0 && count > limit) buffer.append(truncated)
buffer.append(postfix)
return buffer
}
joinTo 함수 내부는 이렇게 구현되어있다.
1. 임의의 prefix 값이 존재한다면 버퍼(StringBuilder)에 prefix값을 추가 한다.
2. 배열을 순회하면서 내부의 count를 전위 연산으로 값을 1 더하고 separator 값을 버퍼에 추가한다.
3. limit 이 0 보다 작고 count가 limit과 같거나 작으면 transform의 null 값을 체크하여 null이 아니라면 transform 함수를 호출하여 변경하고 null 값이라면 배열의 요소를 toString()하여 버퍼에 추가한다.
4.limit 이 0보다 크고 count가 limit보다 클때는 버퍼에 truncated를 추가한다.
5.postfix를 버퍼에 추가한다.
6.완성된 버퍼를 반환한다.
joinToArray로 배열출력을 커스텀 해보자.
prefix 적용시
postfix 적용시
separator 적용시
limit 적용시
truncated 적용시
transform 적용시
transform설명
배열에서 숫자가 하나씩 value로 나오게 되고 나는 value의 조건을 비교해서 다른 값으로 변경하여 출력하도록 하였다.
transform이 존재하기때문에 위의 3번의 로직에서 transform 을 타고 내가 변경하여 반환한 문자열이 버퍼에 추가 되게 되는것이다.
우연히 JoinTo키워드를 알게되어 들여다 보게되었다. 내가 개발하면서 사용할 일이 있을지 의문이 들긴하지만 깨알 같이 유용한 함수들이 코틀린에 많이 숨어있는것 같다.
'Kotlin' 카테고리의 다른 글
[Kotlin] contentToString을 알아보자 (2) | 2022.09.29 |
---|---|
[Kotlin] var / val / const 개념 정리 (0) | 2021.06.22 |