[Kotlin] 6. 함수 정의와 호출
2023. 3. 24. 23:35ㆍProgramming Languages/Kotlin
1. Kotlin에서 Collection 만들기
// java.util.HashSet
val set = hashSetOf(1, 8, 53)
// java.util.ArrayList
val list = arrayListOf(1, 7, 53)
// java.util.HashMap
val map = hashMapOf(1 to "one", 7 to "seven", 53 to "fifty-three")
💡Kotlin은 Java와의 호환을 위해 자체 컬렉션을 제공하지 않고 Java의 컬렉션을 차용함으로써 Java Collection과 Kotlin Collection을 변환할 필요가 없게 설계되었다.
2. 함수를 호출하기 쉽게 만들기
예제 함수
fun <T> joinToString (
collection: Collection<T>,
separator: String,
prefix: String,
suffix: String
): String {
val result = StringBuilder(prefix)
for ((index, elem) in collection.withIndex()) {
if (index > 0) result.append(separator)
result.append(elem)
}
result.append(suffix)
return result.toString()
}
val list = listOf(1, 2, 3)
println(joinToString(list, ", ", "{", "}")
1. named parameter
함수의 인자 이름을 지정하여 값을 지정할 수 있다. 이로써 가독성이 향상되고 Java에서 객체 생성 시 많이 사용되는 Builder 패턴을 대체할 수 있다.
fun <T> joinToString (
collection: Collection<T>,
separator: String,
prefix: String,
suffix: String
): String {
val result = StringBuilder(prefix)
for ((index, elem) in collection.withIndex()) {
if (index > 0) result.append(separator)
result.append(elem)
}
result.append(suffix)
return result.toString()
}
val list = listOf(1, 2, 3)
println(joinToString(
collection = list,
separator = ", ",
prefix = "{",
suffix = "}"
)
2. default parameter
인자값이 없는 경우 기본적으로 사용되는 값을 지정할 수 있다.
fun <T> joinToString (
collection: Collection<T>,
separator: String = ", ",
prefix: String = "[",
suffix: String = "]"
): String {
val result = StringBuilder(prefix)
for ((index, elem) in collection.withIndex()) {
if (index > 0) result.append(separator)
result.append(elem)
}
result.append(suffix)
return result.toString()
}
val list = listOf(1, 2, 3)
println(joinToString(
collection = list,
separator = ", ",
prefix = "{",
suffix = "}"
)
⚠️Java에는 default parameter라는 개념이 없어서 Kotlin 함수를 Java에서 호출하는 경우 그 Kotlin 함수가 default parameter를 제공하더라도 모든 인자를 명시해야 한다. Java에서 Kotlin 함수를 자주 호출한다면 이 부분이 귀찮을 것이다. 이럴 때 @JvmOverloads 어노테이션을 추가할 수 있다. @JvmOverloads를 함수에 추가하면 Kotlin 컴파일러가 자동으로 맨 마지막 파라미터로부터 파라미터를 하나씩 생략한 오버로딩한 Java 메서드를 추가해준다. 예를 들어 위 함수의 경우는 다음과 같이 생성된다.
String joinToString(Collection<T> collection, String separator, String prefix, String postfix);
String joinToString(Collection<T> collection, String separator, String prefix);
String joinToString(Collection<T> collection, String separator);
String joinToString(Collection<T> collection);
3. 정적인 유틸리티 클래스 없애기: 최상위 함수와 프로퍼티
1. 최상위 함수
Java에서는 모든 코드가 클래스 안에 들어가야 하므로 정적 메서드만 모아두는 유틸리티 클래스를 따로 만들어두는 경우가 많았다. Kotlin에서는 이런 무의미한 클래스 없이 함수를 만들 수 있다.
package strings
fun joinToString(...): String { ... }
이 경우 컴파일러는 이 파일을 컴파일할 때 새로운 클래스를 정의해준다. 예를 들어 위 파일의 이름이 join.kt 라고 한다면 컴파일한 결과가 같은 Java 코드는 다음과 같다.
package strings;
public class JoinKt {
public static String joinToString(...) { ... }
}
⚠️Kotlin 최상위 함수가 포함되는 클래스의 이름을 바꾸렬면 파일에 @JvmName 어노테이션을 추가하면 된다.@JvmName은 파일의 맨 앞, 패키지 이름 선언 이전에 위치해야 한다.
@file:JvmName("StringFunction")
package strings
fun joinToString(...): String { ... }
위 함수는 다음과 같이 호출할 수 있다.
import string.StringFunction;
StringFunction.joinToString(list, ", ", "", "");
2. 최상위 프로퍼티
프로퍼티도 파일의 최상위 수준에 놓을 수 있다.
// Kotlin Code
var opCount = 0
fun performOperation() {
opCount++
}
최상위 프로퍼티의 값은 정적(static) 필드에 저장된다.
//Decompile한 Java Code
public final class StringsFunctionKt {
private static int opCount;
public static final int getOpCount() { return opCount; }
public static final int setOpCount() { opCount = var0; }
}
최상위 프로퍼티를 통해 상수를 지정할 수도 있다. val의 경우 getter만, var의 경우 getter, setter가 생긴다.
val opCount = 0
public final class StringsFunctionKt {
private static final int opCount;
public static final int getOpCount() { return opCount; }
}
기본적으로 최상위 프로퍼티도 다른 프로퍼티처럼 getter와 setter로 접근한다. 겉으로는 상수처럼 보이지만 getter와 setter로 접근하는 방법은 자연스럽지 못하다. 따라서 public static final로 정의하는 편이 더 자연스럽다. 이렇게 선언하려면 const 키워드를 함께 사용하면 된다.
const val opCount = 0
public final class StringsFunctionKt {
public static final int opCount;
}
'Programming Languages > Kotlin' 카테고리의 다른 글
[Kotlin] 8. 클래스 계층 정의 (0) | 2023.03.26 |
---|---|
[Kotlin] 7. 메소드를 다른 클래스에 추가: 확장 함수와 확장 프로퍼티 (0) | 2023.03.26 |
[Kotlin] 5. 예외처리 (0) | 2023.03.23 |
[Kotlin] 4. 대상을 이터레이션: while 과 for (0) | 2023.03.23 |
[Kotlin] 3. 선택 표현과 처리: enum과 when (0) | 2023.03.22 |