Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다.
자바 컬렉션 API 확장
이전에 코틀린 컬렉션은 자바와 같은 클래스를 사용하지만 더 확장된 API 를 제공한다고 했다.
@Test
fun collectionExtension() {
val strings: List<String> = listOf("first", "second", "fourteenth")
println(strings.last()) // fourteenth printed
val numbers: Collection<Int> = setOf(1, 14, 2)
println(numbers.max()) // 14 printed
}
이런 코드가 어떻게 작동할까? 어떻게 자바 라이브러리의 컬렉션에 대해 코틀린에서 새로운 기능을 추가할 수 있을까?
`last` 와 `max` 는 확장함수였던 것이다!!!!
`last` 의 구현은 대략 아래처럼 되어 있다.
public fun <T> List<T>.last(): T {
if (isEmpty())
throw NoSuchElementException("List is empty.")
return this[lastIndex]
}
`max` 의 구현은 대략 아래처럼 되어 있다.
public fun <T : Comparable<T>> Iterable<T>.max(): T? {
val iterator = iterator()
if (!iterator.hasNext()) return null
var max = iterator.next()
while (iterator.hasNext()) {
val e = iterator.next()
if (max < e) max = e
}
return max
}
이 밖에 코틀린 표준 라이브러리는 수많은 확장 함수를 포함한다.
이러한 것들을 모두 다 알 필요는 없고 어떤 객체에 사용할 수 있는 메서드나 함수가 궁금할 때마다 IDE 의 코드 완성 기능을 통해 살펴보고, 원하는 함수를 선택하면 된다.
코틀린 표준 라이브러리 참조 매뉴얼을 보면 각 라이브러리 클래스가 제공하는 모든 메서드(멤버 메서드와 확장 함수)를 볼 수 있다.
인자의 개수가 달라질 수 있는 가변 인자 함수
이전에도 계속 사용했듯이 리스트를 생성하는 함수를 호출할 때 원하는 만큼 원소를 전달할 수 있다.
val list = listOf(2, 3, 5, 7, 11)
이 함수의 정의는 아래처럼 되어 있다.
fun <T> listOf(vararg elements: T): List<T> {
return if (elements.size > 0) elements.asList() else emptyList()
}
자바의 가변 인자(`varargs`)는 메서드를 호출할 때 원하는 개수만큼 값을 인자로 넘기면 자바 컴파일러가 배열에 그 값들을 넣어준다.
코틀린의 가변인자도 자바와 비슷하다.
public void printNumbers(int... numbers) {
for (int number : numbers) {
System.out.print(number + " ");
}
}
int[] numbers = {1, 2, 3, 4, 5};
printNumbers(numbers); // 배열을 직접 전달
fun printNumbers(vararg numbers: Int) {
numbers.forEach { number ->
print("$number ")
}
}
val numbers = intArrayOf(1, 2, 3, 4, 5)
printNumbers(*numbers) // 스프레드 연산자를 사용하여 배열을 가변 인자로 전달
자바에서는 타입 뒤에 `...` 을 붙인다.
코틀린에서는 그 대신 파라미터 앞에 `vararg` 변경자를 붙인다.
이미 배열에 들어있는 원소를 가변 길이 인자로 넘길 때도 코틀린과 자바 구문이 다르다.
자바에서는 배열을 그냥 넘기면 된다.
코틀린에서는 배열을 명시적으로 풀어서 배열의 각 원소가 인자로 전달되게 해야 한다.
코틀린 spread(스프레드) 연산자가 그런 작업을 해준다. 전달하려는 배열 앞에 `*` 를 붙여주면 된다.
@Test
fun varargTest() {
val numbers = intArrayOf(1, 2, 3)
printNumbers(*numbers) // 스프레드 연산자를 사용하여 배열을 가변 인자로 전달
printNumbers(*numbers, 4, 5) // 배열의 요소와 추가적인 값들을 함께 전달
}
출력 결과
1 2 3
1 2 3 4 5
위처럼 스프레드 연산자 `*` 를 통하면 배열에 들어있는 값과 다른 추가적인 값들을 함께 써서 함수를 호출할 수 있다.
이런 기능은 자바에서는 사용할 수 없다.
참조 :
'Kotlin' 카테고리의 다른 글
[Kotlin] 문자열 & 정규식 (1) | 2024.01.04 |
---|---|
[Kotlin] 중위 호출 & 구조 분해 선언 (1) | 2024.01.03 |
[Kotlin] 확장 함수 & 확장 프로퍼티 (0) | 2024.01.01 |
[Kotlin] 컬렉션에서의 함수 정의와 호출 (2) | 2024.01.01 |
[Kotlin] 예외 처리 (1) | 2023.12.28 |