컬렉션의 원소를 element; element; element .. 로 출력하는 함수를 만들어보자.
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)
result.append(element)
}
result.append(postfix)
return result.toString()
}
fun main() {
var list = listOf(1, 2, 3)
println(joinToString(list, ";", "(", ")"))
// (1; 2; 3)
}
1 이름 붙인 인자
함수 호출 부분의 가독성을 개선하는 방법으로 코틀린에서는 작성한 함수를 호출할 때 함수에 전달하는 인자 중 일부의 이름을 명시할 수 있다. 호출 시 인자 중 어느 하나라도 이름을 명시하고 나면 혼동을 막기 위해 그 뒤에 오는 모든 인자는 이름을 꼭 명시해야 한다.
joinToString(collection, " ", " ", ".") // 전달한 문자열이 어떤 역할을 하는지 알 수 없다.
joinToString(collection, separator = " ", prefix = " ", postfix = ".")
2 디폴트 파라미터 값
코틀린에서는 함수 선언에서 파라미터의 디폴트 값을 지정할 수 있으므로 자바의 오버로드같은 번거로움을 피할 수 있다. (자바에서는 일부 클래스에서 오버로딩 메소드가 너무 많은 문제가 있다.)
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)
result.append(element)
}
result.append(postfix)
return result.toString()
}
>> joinToString(list) // separator, prefix, postfix 생략
1, 2, 3
>> joinToString(list, postfix = ";", prefix = "# ") // 이름을 지정하면 순서 상관없이 인자를 넘길 수 있다.
3 정적인 유틸리티 클래스 없애기 : 최상위 함수와 프로퍼티
자바에서는 다양한 정적 메소드를 모아두는 역할만 담당하며, 특별한 상태나 인스턴스 메소드는 없는 클래스가 존재한다. (ex. Collections, xxxUtil) 코틀린에서는 이런 무의미한 클래스가 필요 없다. 대신 함수를 직접 소스 파일의 최상위 수준, 모든 다른 클래스의 밖에 위치시키면 된다.
JoinToString 함수를 strings 패키지의 최상위 함수로 선언하기. join.kt
package strings
fun joinToString(..): String { ... }
위와 같은 최상위 함수는 어떻게 실행이 될까?
⇒ JVM이 클래스 안에 들어있는 코드만을 실행할수 있기 때문에 컴파일러는 이 파일을 컴파일할 때 새로운 클래스를 정의해준다.
join.kt를 컴파일한 결과와 같은 클래스를 자바 코드로 써보면 다음과 같다.
package strings;
public class JoinKt{ // join.kt 파일에 해당하는 클래스
public static String joinToString(...) { ... }
}
파일에 대응하는 클래스의 이름 변경하기
코틀린 최상위 함수가 포함되는 클래스 이름을 바꾸고 싶다면 @JvmName 애노테이션을 사용하면 된다.
@file:JvmName("StringFunctions")
package strings
fun joinToString(..): String { ... }
최상위 프로퍼티
var opCount = 0 // 최상위 프로퍼티 선언
val UNIX_LINE_SEPARATOR = "\n"
fun performOperation(){
opCount++
// ..
}
fun reportOperationCount(){
println("Operation performed $opCount times")
}
기본적으로 최상위 프로퍼티도 다른 모든 프로퍼티처럼 접근자 메소드를 통해 자바 코드에 노출된다. (val의 경우 게터, var의 경우 게터와 세터가 생긴다.) 겉은 상수처럼 보이는데, 실제로는 게터를 사용해야 한다면 자연스럽지 못하다. 더 자연스럽게 사용하려면 상수를 public static final 필드로 컴파일해야 한다. 다음과 같이 선언하면 상수스럽게 사용할 수 있다.
const val UNIX_LINE_SEPARATOR = "\n"
// 아래와 같은 자바 코드를 만들어 낸다.
public static final String UNIX_LINE_SEPARATOR = "\n"
'프로그래밍 노트 > Kotlin' 카테고리의 다른 글
[Kotlin] 코틀린 컬렉션 처리: 가변 길이 인자, 중위 함수 호출, 라이브러리 지원 (0) | 2020.11.19 |
---|---|
[Kotlin] 코틀린(Kotlin) 메소드를 다른 클래스에 추가(확장 함수와 확장 프로퍼티) (0) | 2020.11.19 |
[Kotlin] 코틀린(Kotlin)에서 컬렉션 만들기 (0) | 2020.11.14 |
[Kotlin] 코틀린(Kotlin) while과 for 루프 (0) | 2020.11.09 |
[Kotlin] 코틀린(Kotlin) enum과 when (0) | 2020.11.09 |