Kotlin에서 변수 이름 앞의 Kotlin 별표 연산자 또는 스프레드 연산자


97

Kotlin에서 변수 이름 앞에 별표가 정확히 무엇을하는지 알고 싶습니다. Spring boot Kotlin 예제*args 에서 ( )를 보았습니다 .

@SpringBootApplication
open class Application {

    @Bean
    open fun init(repository: CustomerRepository) = CommandLineRunner {
        repository.save(Customer("Jack", "Bauer"))
        repository.save(Customer("Chloe", "O'Brian"))
        repository.save(Customer("Kim", "Bauer"))
        repository.save(Customer("David", "Palmer"))
        repository.save(Customer("Michelle", "Dessler"))
    }
}

fun main(args: Array<String>) {
    SpringApplication.run(Application::class.java, *args)
}

답변:


163

이 *연산자는 Kotlin 에서 스프레드 연산자로 알려져 있습니다.

로부터 코 틀린 참조 ...

vararg 함수를 호출 할 때 인자를 하나씩 전달할 수 있습니다 (예 : asList (1, 2, 3)) 또는 이미 배열이 있고 그 내용을 함수에 전달하려는 경우 spread 연산자 (배열 앞에 *를 붙임) :

를 허용하는 함수로 전달하기 전에 Array에 적용 할 수 있습니다 varargs.

예를 들어 ...

다양한 인수를 받아들이는 함수가 있다면 ...

fun sumOfNumbers(vararg numbers: Int): Int {
    return numbers.sum()
}

이렇게 배열을 전달할 수 있습니다 ...

val numbers = intArrayOf(2, 3, 4)
val sum = sumOfNumbers(*numbers)
println(sum) // Prints '9'

노트:

  • *연산자도이다 곱하기 연산자 (과정).
  • 연산자는 함수에 인수를 전달할 때만 사용할 수 있습니다. 연산 결과는 값이 나오지 않기 때문에 저장할 수 없습니다 ( 순전히 구문 설탕).
  • 연산자는 포인터가 역 참조되는 것처럼 보이기 때문에 처음에 일부 C / C ++ 프로그래머를 혼동 할 수 있습니다. 그렇지 않습니다. Kotlin에는 포인터 개념 이 없습니다 .
  • 이 연산자는 vararg 함수를 호출 할 때 다른 인수 사이에서 사용할 수 있습니다 . 이것은 여기 의 예 에서 설명 됩니다 .
  • 연산자는 apply다양한 기능 프로그래밍 언어 의 기능 과 유사합니다 .

Spread 연산자는 인라인 배열입니까? 예를 들어 배열 a = [1, 2, 3] funWithVararg (* a) inline into funWithVararg (1,2,3)? 나는 바이트 코드 수준을 의미합니다.
— David

22

"이게 뭐야!?!"에 대한 직접 답변 외에도 a를 가지고 있고 List를 예상하는 함수에 전달하려는 경우가 종종 있습니다 vararg. 이를 위해 변환은 다음과 같습니다.

someFunc(x, y, *myList.toTypedArray())

최후의 파라미터를 가정하면, someFunc이다 vararg리스트의 요소와 동일한 유형.


정말 고맙습니다! 이는 스프레드 연산자 섹션 아래의 공식 문서에 있어야 스프레드 연산자가 작동하지 않을 때주의해야합니다.
— pleasedesktop

감사! 정말 도움이됩니다. 무대 뒤에서 "스프레드 연산자"가 무엇인지 궁금하십니까? varargs 값을 얻는 방법입니까?
— Nicolas Jafelle

11

문서에 설명 된대로 이것은 스프레드 연산자입니다.

vararg 함수를 호출 할 때 인자를 하나씩 전달할 수 있습니다 (예 : asList (1, 2, 3)) 또는 이미 배열이 있고 그 내용을 함수에 전달하려는 경우 spread 연산자 (배열 앞에 *를 붙임) :

val a = arrayOf(1, 2, 3) 
val list = asList(-1, 0, *a, 4)

5

vararg (Variable number of arguments) 매개 변수를받는 함수가 다음과 같은 경우 :

fun sum(vararg data:Int)
{
   // function body here         
}

이제이 메서드를 호출하려면 다음을 수행 할 수 있습니다.

sum(1,2,3,4,5)

그러나 다음과 같이 배열에 이러한 값이 있으면 어떻게 될까요?

val array= intArrayOf(1,2,3,4,5)

그런 다음이 메서드를 호출하려면 다음과 같은 스프레드 연산자를 사용해야합니다.

 sum(*array)

여기서 * (확산 연산자)는 해당 배열의 모든 내용을 전달합니다.

* 배열 은 1,2,3,4,5 와 같습니다.

하지만 잠시만 기다려주세요. 다음과 같이 호출하면 sum(array) 유형 불일치 컴파일 시간 오류가 발생합니다.

Type mismatch.
Required:Int
Found:IntArray

문제는 sum함수가 vararg Int매개 변수 (1,2,3,4,5와 같은 값을 허용)를 받아들이고 배열을 전달하면 IntArray.


4

Java에서는 배열을 그대로 전달할 수 있지만 *스프레드 연산자를 사용 하여 배열을 압축 해제하면 스프레드 연산자를 사용하면 단일 호출에서 배열의 값과 일부 고정 값을 결합 할 수 있다는 장점이 있습니다. Java는이를 지원하지 않습니다.


왜 이렇게 구현했는지 스스로에게 물었 기 때문에 찬성했습니다. 아직 100 % 확신하지 못합니다. 내 말은, 그들은 대부분의 경우에 이것을 추론 할 수 없었을까요?
— Tim Büthe

1
@ TimBüthe 어떤 경우에는, 그것을 추론 할 수없는 것, 다음과 같은 경우를 고려 val resultOne = arrayOf(intArrayOne, intArrayTwo)하고 val resultTwo = arrayOf(*intArrayOne, *intArrayTwo). resultOne및의 유형 resultTwo은 각각 Array<Int>및 Array<Array<Int>>입니다. 나는 그 이유 중 하나입니다 믿습니다
— 파리 드
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.