안드 공부를 해볼까?

[확장함수] 코틀린 함수로 호출하기 쉽게 만들기 본문

문법/Kotlin

[확장함수] 코틀린 함수로 호출하기 쉽게 만들기

문바리 2022. 9. 27. 02:19
728x90

2022.09.27 - [문법/Kotlin] - [확장함수] 코틀린에서 컬렉션 만들기

 

[확장함수] 코틀린에서 컬렉션 만들기

기본적인 컬렉션(list, set, map)은 숙지하고 있다고 작성했습니다. 컬렉션 만들기 컬렉션은 **Collection name + Of(value)**로 초기화 합니다. 안에 자료를 넣어주지 않는다면 반드시 자료형을 명시해줘야

moonbari.tistory.com

이전 포스팅에서 계속 됩니다.

 

앞서 본 list를 출력할 때 코틀린은 자바와 다르게 default로 출력이 됩니다.

그렇다면 기존 나오는 [1,2,3]을 {1;2;3}으로 바꿀 수 있을까요?

 

아마 자바에서는 3rd party library나 직접 관련 로직을 구현해야 할겁니다.

반면 코틀린은 이를 직접 구현할 수 있습니다.

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()
}

첫번째와 마지막은 prefix, postfix를 넣어주고 index가 0보다 크다면 separator를 넣어줍니다.

이를 출력하면 결과는 잘 나올 것 입니다. 하지만 아직 우리는 코틀린을 활용하지 못했습니다.

3.2.1 이름 붙인 인자

먼저 위의 함수의 가독성을 더 높여보겠습니다.

자바에서는 함수의 각 parameter가 어떤 것을 의미하는지 표현할려면 다음과 같습니다.

 joinToString(collections, /* separator */ "," , /* prefix */ " ", /*postfix*/ " " =);

하지만 코틀린은 다음과 같이 지원합니다.

joinToString(collection = list, separator = ";", prefix = "{", postfix = "}")

위와 같이 파라미터의 이름을 명시했다면 혼동을 막기위해서 나머지도 명시해주는 것을 권장합니다.

이는 디폴트 파라미터 값을 사용할 때 아주 쓸모가 있습니다.

3.2.2 디폴트 파라미터 값

자바의 Thread는 생성자만 8개가 있습니다. 어떻게 하든 결과는 똑같은데 말이죠.

개발자들은 각 상황에 맞게 쓸 수 있지만 이는 개발자 마다 설명을 반복하는 일이 발생합니다.

코틀린에서는 함수 선언 시, 파라미터의 디폴트 값을 지정할 수 있습니다.

fun <T> joinToString(
    collection: Collection<T>,
    separator: String = ", ",
    prefix: String = "",
    postfix: String = ""
): String

//1
joinToString(list)
>>> 1, 2, 3

//2
joinToString(list, "; ")
>>> 1; 2; 3

//3
joinToString(list, ";", "{", "}")
>>> {1; 2; 3}

1번 같은 경우 separator와 prefix, postfix가 전부 default로 들어갔습니다.

2번은 separator만 “; “로 변경된 상태입니다.

3번은 separator, prefix, postfix 전부 변경된 상태입니다,

단, default 가 없는 파라미터는 반드시 넣어주어야 합니다.

joinToString(list, prefix = "{", postfix = "}")

또한, 중간의 파라미터값을 default로 처리할 때는 반드시 파라미터를 명시적으로 표현해줘야합니다.

3.2.3 정적인 유틸리티 클래스 없애기: 최상위 함수와 프로퍼티

기존 자바에서는 모든 코드를 클래스의 메서드로 작성해야 사용할 수 있었습니다.

하지만 어느 한 클래스에 정의해서 사용하기 어려운 코드들이 존재하고 많은 클래스를 생성하는 경우도 존재합니다.

코틀린에서는 이러한 정적 메서드를 인스턴스화 없이 사용할 수 있습니다.

단, 함수를 최상위 수준으로 올리거나, 사용하고자하는 클래스 밖에 위치시켜야 합니다.

앞서 본 joinToString을 join.kt로 옮겨서 사용해보겠습니다.

package stringns

import java.lang.StringBuilder

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()
}

main에 있는 joinToString을 지우고 join.kt를 추가했을 때, 기존 사용했던 joinToString은 그대로 사용할 수 있습니다. 이 함수는 어떻게 사용할 수 있는걸까요?

public class JoinKt{
	public static String joinToString(...){ ... }
}

자바로 표현한다면 위와같은 클래스가 생기게 됩니다.

물론 코틀린만 사용한다면 숙지할 필요가 없지만 자바와 혼용해서 사용하거나 다른 JVM에서 사용해야한다면 숙지해야합니다.

추가: 최상위 함수 내부에 프로퍼티 추가

var count = 0

fun performOperation(){
    count++
}

fun reportOperationCount(){
    println("Operation performed $count times")
}

프로퍼티같은 경우, var과 val을 선언할 수 있습니다.

하지만 var는 getter와 setter가 2개 생성되지만 val은 getter만 존재합니다.

따라서 val은 const val로 선언하는 것이 더 올바릅니다.

반응형
Comments