Оператор звездочки Kotlin до имени переменной или оператора Spread в Котлине
Я хочу знать, что именно звездочка делает до имени переменной в Kotlin.
Я видел это (*args
) в Spring загрузите пример Kotlin:
@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)
}
Ответы
Ответ 1
Оператор *
известен как оператор распространения в Kotlin.
Из Kotlin Reference...
Когда мы вызываем функцию vararg, мы можем передавать аргументы один за другим, например, asList (1, 2, 3) или, если у нас уже есть массив и мы хотим передать его содержимое в функцию, мы используем оператор распространения (префикс массива *):
Его можно применить к массиву перед передачей в функцию, которая принимает 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++, поскольку похоже, что указатель на него не ссылается. Это не так; Котлин не имеет представления об указателях.
- Оператор может использоваться между другими аргументами при вызове функции vararg. Это продемонстрировано в примере здесь.
- Оператор аналогичен функции
apply
в различных функциональных языках программирования.
Ответ 2
В дополнение к ответам, которые были непосредственно направлены на "что это за штука!?!", вы часто имеете случай, когда у вас есть List
и хотите передать его функции, ожидающей vararg
. Для этого преобразование:
someFunc(x, y, *myList.toTypedArray())
Предполагая, что последний параметр someFunc
равен vararg
того же типа, что и элементы в списке.
Ответ 3
Как описано в документации, это оператор с расширением:
Когда мы вызываем vararg-функцию, мы можем передавать аргументы один за другим, например. asList (1, 2, 3), или, если мы уже имеем массив и хотим передать его содержимое функции, мы используем оператор спрединга (префикс массива с *):
val a = arrayOf(1, 2, 3)
val list = asList(-1, 0, *a, 4)
Ответ 4
В Java вы можете передать массив как есть, но преимущество распаковки массива с оператором распространения *
заключается в том, что оператор spread позволяет объединить значения из массива и некоторые фиксированные значения в одном вызове. Java не поддерживает это.
Ответ 5
Если функция, которая принимает параметр vararg (переменное число аргументов), например:
fun sum(vararg data:Int)
{
// function body here
}
Теперь, чтобы вызвать этот метод, мы можем сделать:
sum(1,2,3,4,5)
Но что, если у нас есть эти значения в массиве, например:
val array= intArrayOf(1,2,3,4,5)
затем, чтобы вызвать этот метод, мы должны использовать оператор распространения, например:
sum(*array)
Здесь * (оператор распространения) пропустит все содержимое этого массива.
*array is equivalent to 1,2,3,4,5
Но подождите минутку, что если мы назовем это так: sum(array)
это даст нам ошибку несоответствия типов:
Type mismatch.
Required:Int
Found:IntArray
Проблема в том, что функция sum
принимает параметр vararg Int
(который принимает значение, например: 1,2,3,4,5), и если мы передадим массив, он будет передан как IntArray
.