fun <T> joinToString(
collection: Collection<T>,
separator: String,
prefix: String,
postfix: String
) : String {
val result = StringBuilder(prefix)
for((index, element) in collection.withIndex()) {
if (index > 0) result.append(separator) // 첫 원소 앞에는 구분자를 붙이지 않기 위한 if문 ( 아래 함수 출력 결과 참고)
result.append(element)
}
result.append(postfix)
return result.toString()
이 함수는 제네릭하다. 즉, 이 함수는 어떤 타입의 값을 원소로 하는 컬렉션이든 처리할 수 있다는 뜻이다.
다음은 함수 출력 결과다.
-> val list = listOf(1,2,3)
-> println(joinToString(list,"; ", "(", ")"))
(1; 2; 3)
어떻게 하면 이 함수를 덜 번잡하게 만들 수 있을까? 함수를 호출할 때마다 매번 네 인자를 모두 전달하지 않을 수는 없을까?
joinToString(collection, separator = " ", prefix = " ", postfix = ".")
코틀린으로 작성한 함수를 호출할 때는 함수에 전달하는 인자 중 일부(또는 전부)의 이름을 명시할 수 있다. (자바는 불가능)
호출 시 인자 중 어느 하나라도 이름을 명시하고 나면 혼동을 막기 위해 그 뒤에 오는 모든 인자는 이름을 꼭 명시해주자.
자바에서는 일부 클래스에서 오버로딩한 메서드가 너무 많아진다는 문제가 있다.
코틀린에서는 함수 선언에서 파라미터의 디폴트 값을 지정할 수 있으므로 이런 오버로드 중 상당수를 피할 수 있다.
디폴트 값을 사용해 joinToString 함수를 개선해보자.
fun <T> joinToString(
collection: Collection<T>,
separator: String = ", ",
prefix: String = "",
postfix: String = "" // 디폴트 값이 지정된 파라미터들
) : String
이제 함수를 호출할 때 모든 인자를 쓸 수도 있고, 이부를 생략할 수도 있다.
-> joinToString(list, ", ", "", "")
1, 2, 3
-> joinToString(list) // separator, prefix, postfix 생략
1, 2, 3
-> joinToString(list, "; ") // separator를 "; "로 지정. prefix 와 postfix 생략
1; 2; 3
일반 호출 문법을 사용하려면 함수를 선언할 때와 같은 순서로 인자를 지정해야 한다.
그러나 이름이 붙은 인자를 사용하는 경우에는 인자 목록의 중간에 있는 인자를 생략하고, 지정하고 싶은 인자를 이름을 붙여서 순서와 관계없이 지정할 수 있다.
-> joinToString(list, postfix = ";", prefix = "# ")
# 1, 2, 3;
디폴트 값과 자바
자바에는 디폴트 파라미터 값이라는 개념이 없어서 코틀린 함수를 자바에서 호출하는 경우에는 그 코틀린 함수가 디폴트 파라미터 ㄱ밧을 제공하더라도 모든 인자를 명시해야 한다. 자바에서 코틀린 함수를 자주 호출해야 한다면 자바 쪽에서 좀 더 편하게 코틀린 함수를 호출하고 싶을 것이다. 그럴 때 @JvmOverloads 애노테이션을 함수에 추가할 수 있다. @JvmOverloads를 함수에 추가하면 코틀린 컴파일러가 자동으로 맨 마지막 파라미터로부터 파라미터를 하나씩 생략한 오버로딩한 자바 메서드를 추가해준다.
예를 들어, joinToString에 @Jvmoverloads를 붙이면 다음과 같은 오버로딩한 함수가 만들어진다.
/ 자바 /
String joinTOString(Collection collection, String separator, String prefix, String postfix);
String joinToString(Collection collection, String separator, String prefix);
String joinToString(Collection collection, String separator);
String joinToString(Collection collection);
각각의 오버로딩한 함수들은 시그니처에서 생략된 파라미터에 대해 코틀린 함수의 디폴트 파라미터 값을 사용한다.
하.. 기초가 부족한건지 프로젝트 설계 경험이 부족해서인지 도저히 뭔지 감이 잘 안온다.. 이정도 사이즈의 모르는 부분은 기술부채로 남겨두고 나중에 다시 감이 오는 것 같다 싶을 때 찾아봐야 겠다.