2017-06-16 6 views
42

और बदली न्यूबी पूछती है, "निम्नलिखित कोड संकलित क्यों नहीं होगा?":'कास्ट' पर स्मार्ट कास्ट असंभव है, क्योंकि 'वेरिएबल' एक म्यूटेबल प्रॉपर्टी है जो इस समय

var left: Node? = null 

    fun show() { 
     if (left != null) { 
      queue.add(left) // ERROR HERE 
     } 
    } 
क्योंकि 'छोड़' एक परिवर्तनशील संपत्ति है कि इस बार

मुझे लगता है कि left परिवर्तनशील चर रहा है पाने के द्वारा बदला जा सकता था है

'नोड' के लिए स्मार्ट डाली, असंभव है , लेकिन मैं स्पष्ट रूप से left != null और left की जांच कर रहा हूं Node का प्रकार है तो यह उस प्रकार के स्मार्ट-जाति क्यों नहीं हो सकता है?

मैं इसे सुंदर ढंग से कैसे ठीक कर सकता हूं? :)

+2

कहीं अलग थ्रेड के बीच में मूल्य को फिर से शून्य में बदल दिया होगा। मुझे यकीन है कि अन्य सवालों के जवाब भी निश्चित हैं। – nhaarman

+1

आप – Whymarrh

+0

को जोड़ने के लिए एक [सुरक्षित कॉल] (https://kotlinlang.org/docs/reference/null-safety.html#safe-calls) का उपयोग कर सकते हैं धन्यवाद @ नहरमन जो समझ में आता है, Whymarrh यह कैसे कर सकता है? मैंने सोचा कि सुरक्षित कॉल केवल ऑब्जेक्ट्स के लिए नहीं थे – feresr

उत्तर

60

n.left != null और queue.add(n.left) के निष्पादन के बीच एक और धागा null को n.left का मूल्य बदल गया होगा।

इस पर काम करने के लिए आपके पास कई विकल्प हैं। एक साथ

n.left?.let { left -> queue.add(left) } 
n.left?.let { queue.add(it) } 
n.left?.let(queue::add) 
  • उपयोग Elvis operator:

    val left = n.left 
    if (left != null) { 
        queue.add(left) 
    } 
    
  • उपयोग एक safe call इस तरह के निम्न में से एक के रूप में:

    1. स्मार्ट कलाकारों के साथ एक स्थानीय चर का उपयोग करें: यहाँ कुछ कर रहे हैं jump संलग्न while लूप के अगले चरण में:

      queue.add(n.left ?: continue) 
      
  • +0

    4. अपनी समस्या के लिए एक अधिक कार्यात्मक समाधान के बारे में सोचें जिसमें म्यूटेबल चर की आवश्यकता नहीं है। –

    1

    mfulton26 के उत्तर में लोगों के अलावा चौथा विकल्प है।

    ?. ऑपरेटर का उपयोग करके let से निपटने या स्थानीय चर का उपयोग किए बिना विधियों के साथ-साथ फ़ील्ड को कॉल करना संभव है।

    संदर्भ के लिए कुछ कोड:

    var factory: ServerSocketFactory = SSLServerSocketFactory.getDefault(); 
    socket = factory.createServerSocket(port) 
    socket.close()//smartcast impossible 
    socket?.close()//Smartcast possible. And works when called 
    

    यह विधियां, फ़ील्ड और सभी अन्य बातों के मैं यह काम करने के लिए प्राप्त करने की कोशिश के साथ काम करता है।

    इसलिए समस्या को हल करने के लिए, मैन्युअल कास्ट या स्थानीय चर का उपयोग करने के बजाय, आप विधियों को कॉल करने के लिए ?. का उपयोग कर सकते हैं।

    संदर्भ के लिए, यह कोटलिन 1.1.4-3 में परीक्षण किया गया था, लेकिन 1.1.51 और 1.1.60 में भी परीक्षण किया गया था। इस बात की कोई गारंटी नहीं है कि यह अन्य संस्करणों पर काम करता है, यह एक नई सुविधा हो सकती है।

    ?. ऑपरेटर का उपयोग आपके मामले में नहीं किया जा सकता है क्योंकि यह एक पारित चर है जो समस्या है। एल्विस ऑपरेटर को एक विकल्प के रूप में इस्तेमाल किया जा सकता है, और शायद यह वह है जिसके लिए कम से कम कोड की आवश्यकता होती है। continue का उपयोग करने के बजाय, return का भी उपयोग किया जा सकता है।

    मैनुअल कास्टिंग का उपयोग करना भी एक विकल्प हो सकता है, लेकिन इस अशक्त सुरक्षित नहीं है:

    queue.add(left as Node); 
    

    अर्थ अगर छोड़ दिया एक अलग धागे पर बदल गया है, कार्यक्रम दुर्घटना होगा।

    +0

    जहां तक ​​मैं समझता हूं, '?' ऑपरेटर जांच कर रहा है कि उसके बाईं तरफ परिवर्तनीय शून्य है .. ऊपर दिए गए उदाहरण में यह 'कतार' होगा। 'स्मार्ट कास्ट असंभव' त्रुटि "एड" विधि में पारित पैरामीटर "बाएं" का जिक्र कर रही है ... अगर मैं इस दृष्टिकोण का उपयोग करता हूं तो मुझे अभी भी त्रुटि मिलती है – feresr

    +0

    सही, त्रुटि 'बाएं' पर है और कतार नहीं है '। इसे जांचने की आवश्यकता है, एक मिनट में जवाब संपादित करेंगे – Zoe

    संबंधित मुद्दे