Develop!/Kotlin

이름 붙은 인자, 가변인자 in kotlin

체리필터 2023. 8. 16. 14:36
728x90
반응형

어떤 함수에 인자값을 전달할 때 인자의 개수들이 많다면 지금 넘기는 값이 어떤 인자에 해당하는지 알 기 어려운 경우가 많다. 그래서 클린 코드를 위해 가능하면 인자의 개수를 줄이는 행동들도 많이 한다.

이러한 어려움을 해결하기 위해 코틀린에서는 인자의 이름을 명시적으로 붙여서 전달할 수 있도록 만들어 둔 것 같다.

fun color (red: Int, green: Int, blue: Int) = "($red, $green, $blue)"

fun nameArgument() {
    println(color(1, 2, 3))
    println(
        color(
            red = 76,
            green = 89,
            blue = 0,
        )
    )
    println(color(52, 34, blue = 0))
}

color라는 함수에 red, green, blue라는 인자값을 3개 받도록 했는데 사용하는 입장에서 파라미터의 순서를 기억하고 사용하기란 쉽지 않다.

그나마 ide에서 지원해주는 기능들을 통해 지금 입력하는 인자가 무엇인지 도움을 받을 수 있지만 그렇지 않을 경우에는 어렵다.

코틀린에서는 인자값을 명시해서 전달할 수 있다. 위의 예를 실행해 보면 아래와 같다.

호출하는 인자값에 이름을 붙이기 때문에 순서를 바꿔서 호출할 수도 있다.

fun paramSequence() {
    println(color(blue = 0, red = 99, green = 52))
    println(color(red = 255, 255, 0))
}

원래 순서는 red, green, blue 였지만 명시해서 호출하게 되면 순서가 바뀌어도 된다. 순서를 바꿔서 호출하게 될 경우에는 나머지 인자도 이름을 붙여 주어야 한다. 컴파일러가 순서를 알 수 없기 때문이다. 위 내용을 실행하면 아래와 같다.

인자 값에 기본 값을 지정할 수도 있다.

fun color (red: Int, green: Int, blue: Int) = "($red, $green, $blue)"

fun color2(
    red: Int = 0,
    green: Int = 0,
    blue: Int =0
) = color(red, green, blue)

fun defaultValue() {
    println(color2())
    println(color2(139))
    println(color2(blue = 139))
    println(color2(255, 165))
}

color2 라는 함수에는 각각의 인자 기본값을 0으로 만들어 두었다. 이를 확인해 보기 위해 defaultValue 함수를 실행해 보면 다음과 같다.

첫 번째 실행은 기본값 0으로 나온 것을 볼 수 있다. 그냥 한 개의 인자값을 넘긴 경우에는 첫 번째 red 인자에 값이 들어간다.

blue라고 이름을 명시하고 값을 넘기면, blue에만 넘긴 값이 적용되고 나머지는 기본 값이 출력된다. 2개를 넘기게 되면 앞에서부터 순서대로 2개의 값만 들어가고 나머지는 기본 값이 사용되어지게 된다.

이런 기본 인자값을 사용한 함수 중에는 joinToString 이란 함수가 있다.

joinToString에는 3개의 인자값이 있다.

/**
 * Creates a string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied.
 * 
 * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit]
 * elements will be appended, followed by the [truncated] string (which defaults to "...").
 * 
 * @sample samples.collections.Collections.Transformations.joinToString
 */
public fun <T> Iterable<T>.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): String {
    return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString()
}

위에 정의 된 함수에서 볼 수 있는 것 처럼 separator는 "," prefix와 postfix는 빈 문자열이 사용 된다. (그 외 인자들에도 비슷하게 기본 값이 할당 되어 있다)

따라서 아래와 같이 만들어 놓은 list를 사용해서 joinToString을 실행해 보면 예상한 대로 결과가 나오는 것을 볼 수 있다.

fun joinToString() {
    val list = listOf(1, 2, 3,)
    println(list.toString())
    println(list.joinToString())
    println(list.joinToString(prefix = "(", postfix = ")"))
    println(list.joinToString(separator = ":"))
}

list 자체를 실행 하면 []를 사용해서 표현해 주지만 joinToString을 사용하면 기본값을 잘 사용해서 보여주고 있다.

물론 기본 값을 바꿔서 실행해 볼 수도 있다.

이런 기본 인자값을 활용한 기본 함수들이 많이 있는데 trimMargin과 같은 함수들도 있다.

/**
 * Trims leading whitespace characters followed by [marginPrefix] from every line of a source string and removes
 * the first and the last lines if they are blank (notice difference blank vs empty).
 *
 * Doesn't affect a line if it doesn't contain [marginPrefix] except the first and the last blank lines.
 *
 * Doesn't preserve the original line endings.
 *
 * @param marginPrefix non-blank string, which is used as a margin delimiter. Default is `|` (pipe character).
 *
 * @sample samples.text.Strings.trimMargin
 * @see trimIndent
 * @see kotlin.text.isWhitespace
 */
public fun String.trimMargin(marginPrefix: String = "|"): String =
    replaceIndentByMargin("", marginPrefix)
fun trimMargin() {
    val poem = """
       |->Last night I saw upon the stair
        |->A little man who wasn't there
    """
    println(poem.trimMargin())
    println(poem.trimMargin(marginPrefix = "|->"))
}

공백을 제외하고 첫 번째 글자를 제거해 주는 함수인데 marginPrefix 인자값을 기본값이 아니라 다른 값으로 넘기게 되면 결과값이 달라지게 된다.

기본 값은 공백을 제외한 첫 번째 글자 값이니 "|"만 제거 되었지만 marginPrefix에 "|->"까지 넣게 될 경우 그 다음 글자부터 나오게 된다.

 

728x90
반응형

'Develop! > Kotlin' 카테고리의 다른 글

when in kotlin  (0) 2023.08.23
오버로딩(OverLoading) in Kotlin  (0) 2023.08.18
확장함수 in kotlin  (0) 2023.08.14
Property in kotlin  (0) 2023.08.07
Map in Kotlin  (0) 2023.08.04