कोटलिन में वैरिएबल नाम या स्प्रेड ऑपरेटर से पहले कोटलिन तारांकन ऑपरेटर


97

मैं जानना चाहता हूं कि कोटलिन में चर नाम से पहले वास्तव में तारांकन क्या करता है। मैंने इसे ( *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)
}

जवाबों:


161

*ऑपरेटर के रूप में जाना जाता है फैले ऑपरेटर Kotlin में।

से Kotlin संदर्भ ...

जब हम एक वार्ग-फंक्शन कहते हैं, तो हम एक-एक करके तर्क पारित कर सकते हैं, उदाहरण के लिए (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 ++ प्रोग्रामर को भ्रमित कर सकता है क्योंकि ऐसा लगता है कि एक संकेतक डी-रेफ़र किया जा रहा है। यह नहीं है; कोटलिन में संकेतकर्ताओं की कोई धारणा नहीं है
  • Vargg फ़ंक्शन को कॉल करते समय ऑपरेटर का उपयोग अन्य तर्कों के बीच किया जा सकता है । इसका उदाहरण यहां दिया गया है
  • ऑपरेटर applyविभिन्न कार्यात्मक प्रोग्रामिंग भाषाओं में फ़ंक्शन के समान है ।

स्प्रेड ऑपरेटर इनलाइन सरणी है? उदाहरण के लिए सरणी के लिए a = [1, 2, 3] funWithVararg (* a) इनलाइन in funWithVararg (1,2,3)? मेरा मतलब है कि बाइटकोड स्तर में।
डेविड

22

उन उत्तरों के अलावा जो सीधे "यह क्या बात है!" के प्रति हैं, आपके पास अक्सर ऐसा मामला होता है जहां आपके पास एक है Listऔर इसे उस फ़ंक्शन को पास करना चाहते हैं जो उम्मीद कर रहा है vararg। इसके लिए, रूपांतरण है:

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

की है कि पिछले पैरामीटर मान लिया जाये कि someFuncहै varargसूची में तत्व के रूप में एक ही प्रकार के।


आपको बहुत - बहुत धन्यवाद! स्प्रेड ऑपरेटर सेक्शन के तहत यह आधिकारिक डॉक्स में होना चाहिए क्योंकि जब आपका फैला हुआ ऑपरेटर काम नहीं कर रहा होता है तो उसे कुछ देखना होता है।
प्रसन्नचित्त

धन्यवाद! वास्तव में उपयोगी। आश्चर्य है कि पर्दे के पीछे "स्प्रेड ऑपरेटर" क्या है? क्या केवल एक वैरैगस मूल्य प्राप्त करने का एक तरीका है?
निकोलस जफेल

11

दस्तावेज़ में वर्णित के रूप में यह एक प्रसार ऑपरेटर है:

जब हम एक वार्ग-फंक्शन कहते हैं, तो हम एक-एक करके तर्क पारित कर सकते हैं, उदाहरण के लिए (1, 2, 3), या, यदि हमारे पास पहले से ही एक सरणी है और फ़ंक्शन में इसकी सामग्री को पास करना चाहते हैं, तो हम प्रसार का उपयोग करते हैं ऑपरेटर (* के साथ सरणी उपसर्ग):

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

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)

यहां, * (प्रसार ऑपरेटर) उस सरणी की सभी सामग्री को पास करेगा।

* सरणी 1,2,3,4,5 के बराबर है

लेकिन एक मिनट प्रतीक्षा करें, अगर हम इसे इस तरह कहते हैं: sum(array) यह हमें टाइप मिसमैच संकलन समय त्रुटि देगा:

Type mismatch.
Required:Int
Found:IntArray

समस्या यह sumहै कि एक vararg Intपैरामीटर स्वीकार करें (जो मान को स्वीकार करें: 1,2,3,4,5) और यदि हम सरणी पास करते हैं, तो इसे पास किया जाएगा IntArray


4

जावा में आप एक सरणी पास कर सकते हैं, लेकिन प्रसार ऑपरेटर के साथ एक सरणी को अनपैक करने का एक फायदा *यह है कि प्रसार ऑपरेटर आपको एक सरणी से मानों और कुछ निश्चित मानों को एक कॉल में संयोजित करने देता है। जावा इसका समर्थन नहीं करता है।


अपवित्र, क्योंकि मैंने खुद से पूछा कि उन्होंने इसे इस तरह क्यों लागू किया। मैं अभी भी इसके बारे में 100% निश्चित नहीं हूं। मेरा मतलब है, क्या वे ज्यादातर मामलों में इसका पता नहीं लगा सकते हैं?
टिम बुथ

1
@ TimBüthe कुछ मामलों में, यह अनुमान लगाना संभव नहीं होगा, निम्नलिखित मामलों पर विचार करें val resultOne = arrayOf(intArrayOne, intArrayTwo)और val resultTwo = arrayOf(*intArrayOne, *intArrayTwo)। प्रकार resultOneऔर resultTwoक्रमशः हैं Array<Int>और Array<Array<Int>>। मेरा मानना ​​है कि इसका एक कारण है
फरीद
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.