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.