Skils/Kotlin

[Kotlin] vararg(가변인자)

재한 2022. 8. 12. 21:47

자바와 마찬가지로 코틀린도 가변 인자를 지원한다.

가변 인자를 사용하면 함수를 호출할 때 인자의 개수를 자유롭게 지정할 수 있다.

사용하려면 파리 미터 앞에 vararg를 붙이면 된다.


fun printSort(vararg items:Int){
    items.sort()
    println(items.contentToString())
}
fun main(){
    printSort(1) // [1]
    printSort(1,4,3,2) // [1,2,3,4]
}

위에서 보듯이 vararg를 items 앞에 붙여주니 인자의 개수를 마음대로 사용하고 적절한 배열 타입으로 사용할 수 있다.

💡스프레드(spread)연산자인 *를 사용하면 배열을 가변 인자 대신 넘길 수 있다.

fun printSort(vararg items:Int){
    items.sort()
    println(items.contentToString())
}
fun main(){
    val num = intArrayOf(6,2,10,1)
    printSort(num) //오류 발생 num은 intArray 타입이기 때문에 파라미터의 타입이 다름.
    printSort(*num) //*을 이용해서 배열을 가변인자로 넘겨주면 오류가 발생하지 않음.
}

스프레드(*)배열을 복사한다!

따라서 파라미터의 배열을 바꿔도 원본 원소에는 영향을 미치지 않는다.

fun printSort(vararg items:Int){
    items.sort()
    println(items.contentToString())
}
fun main(){
    val num = intArrayOf(6,2,10,1)
    printSort(*num)  // [1,2,6,10]출력
    println(num.contentToString()) //[6,2,10,1]출력 가변인자로 넘겨줬기 때문에 원래의 원소에는 영향을 미치지 못했음.
}

스프레드를 사용하면 얕은 복사가 이뤄진다.

🔎얕은 복사란?

주소값을주소 값을 그대로 복사한다는 의미이다.

배열 내부에 참조가 들어있는 경우 참조가 복사되기 때문에 참조가 가리키는 데이터가 호출하는 쪽(원본)과 함수 내부 배열에서는 공유된다.

⚡반드시 참조가 있어야 공유함!

fun change(vararg item : IntArray){
    item[0][0]=100
}
fun main(){
    val a= intArrayOf(1,2,3)
    val b= intArrayOf(2,3,4)
    change(a)
    change(b)
    println(a.contentToString()) //[100,2,3]출력
    println(b.contentToString()) //[100,3,4]출력
}

함수 내부에 배열에 대한 참조가 있어서 a, b의 0번지가 100으로 바뀐 것을 알 수 있다.

 

💡둘 이상을 vararg 파라미터로 선언하는 것은 금지된다.

하지만 vararg 파라미터에 콤마로 분리한 여러 인자와 스프레드를 섞어서 전달하는 것은 괜찮다.

[호출은 원래의 순서가 유지되는 단일 배열로 합쳐진다]

printsort(6,1,*intArrayOf(3,8),2) //6,1,3,8,2 순서로 원소가 들어있는 배열이 함수에 전달됨.
//[1,2,3,6,8]이 출력됨.

vararg 파라미터 이후의 파라미터는 이름 붙은 인자로만 전달할 수 있기 떄문에 vararg 파라미터를 파라미터 목록의 맨 뒤에 위치하는 것이 깔끔한 코딩이다.!

vararg는 오버 로딩 해소에도 영향을 미친다.

다른 요소가 모두 같다면 vararg 파라미터가 있는 함수는 동일한 타입의 파라미터 수가 고정돼 있는 함수보다 덜 구체적인함수로 간주된다.

fun printSort(vararg item : Int){ //1번
    println("가")
}
fun printSort(a: Int, b: Int, c:Int){ //2번
    println("아")
}
fun main(){
 printSort(1,2,3)  //아 출력
 printSort(1,2) //가 출력
}
  • printSort(1,2,3)은 1번과 2번을 둘 다 선택할 수 있지만, 1번은 가변 인자 함수이므로 덜 구체적으로 간주되어서 컴파일러는 2번을 선택한다.
  • printSort(1,2)는 적용할 수 있는 함수가 2번 밖에 없기 때문에 2번을 선택한다.

정리

  • 코틀린에는 vararg라는 가변 인자가 있다.
    • 이것을 통해서 함수 호출 파라미터의 개수를 유동적으로 넘겨줄 수 있고, 적절한 배열 타입으로도 변환 가능하다.
  • spread(스프레드) 연산자인 *을 사용하면 배열을 가변 인자 대신 넘길 수 있다.
    • 스프레드는 배열을 복사하지만 얕은 복사를 하기 때문에 실제로 원본 데이터의 영향을 미치지 못한다.
    • 하지만 함수 내부에서 참조를 한다면 원본 데이터와 함수 내부 데이터가 공유된다.
  • 둘 이상을 vararg 파라미터로 선언하는 것은 금지이지만, 콤마로 분리해서 여러 인자와 스프레드를 섞어서 전달하는 것은 가능하다.
  • vararg 파라미터 이후의 파라미터는 이름 붙은 인자로만 전달할 수 있다.
  • vararg를 사용한 함수는 그렇지 않은 함수보다 덜 구체적인 함수로 간주된다.