2015-09-07 5 views
8

मेरे पास निम्न कोड है जो स्प्रे-जेसन का उपयोग कुछ JSON को केस क्लास में parseJson विधि के माध्यम से deserialise करने के लिए करता है।स्केल प्रभाव को हल करते समय स्पष्ट प्रकारों का उपयोग कैसे करता है?

जहां पर अंतर्निहित जेसनफॉर्मैट [माईसेज़ क्लास] परिभाषित किया गया है (साथी वस्तु से ऑनलाइन या आयात किया गया है), और परिभाषित होने पर प्रदान किया गया एक स्पष्ट प्रकार है, तो कोड संकलित नहीं हो सकता है।

मुझे समझ में नहीं आ रहा है कि साथी ऑब्जेक्ट से अंतर्निहित आयात करने के लिए इसे परिभाषित होने पर एक स्पष्ट प्रकार की आवश्यकता होती है, लेकिन यदि मैं इसे इनलाइन डालता हूं, तो ऐसा नहीं है?

दिलचस्प बात यह है कि IntelliJ सभी मामलों में अंतर्निहित पैरामीटर (cmd-shift-p के माध्यम से) को सही ढंग से ढूंढता है।

मैं स्कैला 2.11.7 का उपयोग कर रहा हूं।

टूटी कोड - साथी वस्तु से वाइल्डकार्ड आयात, अनुमानित प्रकार: में

import SampleApp._ 
import spray.json._ 

class SampleApp { 
    import MyJsonProtocol._ 
    val inputJson = """{"children":["a", "b", "c"]}""" 
    println(s"Deserialise: ${inputJson.parseJson.convertTo[MyCaseClass]}") 
} 

object SampleApp { 
    case class MyCaseClass(children: List[String]) 

    object MyJsonProtocol extends DefaultJsonProtocol { 
    implicit val myCaseClassSchemaFormat = jsonFormat1(MyCaseClass) 
    } 
} 

परिणाम:

Cannot find JsonReader or JsonFormat type class for SampleAppObject.MyCaseClass 

ध्यान दें कि एक ही बात myCaseClassSchemaFormat निहित की एक स्पष्ट आयात के साथ होता है।

कार्य संहिता # 1 - साथी वस्तु से वाइल्डकार्ड आयात, स्पष्ट प्रकार:

साथी वस्तु में JsonFormat का सुस्पष्ट प्रकार जोड़ना कोड को संकलित करने का कारण बनता है:

import SampleApp._ 
import spray.json._ 

class SampleApp { 
    import MyJsonProtocol._ 
    val inputJson = """{"children":["a", "b", "c"]}""" 
    println(s"Deserialise: ${inputJson.parseJson.convertTo[MyCaseClass]}") 
} 

object SampleApp { 
    case class MyCaseClass(children: List[String]) 

    object MyJsonProtocol extends DefaultJsonProtocol { 
    //Explicit type added here now 
    implicit val myCaseClassSchemaFormat: JsonFormat[MyCaseClass] = jsonFormat1(MyCaseClass) 
    } 
} 

कार्य कोड # 2 - इनलाइन, अनुमानित प्रकार:

हालांकि, इन्हें अंतर्निहित पैरामीटर इन-लाइन डालने पर उपयोग किया जाता है, बिना स्पष्ट प्रकार, यह भी काम करता है!

import SampleApp._ 
import spray.json._ 

class SampleApp { 
    import DefaultJsonProtocol._ 

    //Now in-line custom JsonFormat rather than imported 
    implicit val myCaseClassSchemaFormat = jsonFormat1(MyCaseClass) 

    val inputJson = """{"children":["a", "b", "c"]}""" 
    println(s"Deserialise: ${inputJson.parseJson.convertTo[MyCaseClass]}") 
} 

object SampleApp { 
    case class MyCaseClass(children: List[String]) 
} 
+0

यह उन लोगों में से एक है "जब मैं ऐसा करता हूं तो यह दर्द होता है" प्रश्न जहां सबसे अच्छा जवाब लगभग निश्चित रूप से "अच्छा नहीं है"। मेरे अनुभव में टाइप एनोटेशन की कमी वाले अंतर्निहित मूल्य स्कैला में भ्रम के सबसे आम स्रोतों में से एक हैं, व्यवहार में अजीब क्रॉस-वर्जन अंतर, इत्यादि। –

+0

हाय ट्रैविस - वास्तव में, यह काम करने के लिए एक दिलचस्प बग था, लेकिन मुझे लगता है कि अगली बार टाइप एनोटेशन इसी तरह के मुद्दों के लिए मेरा पहला बंदरगाह होगा! यह सुनिश्चित नहीं है कि यह स्केल बग के रूप में गिना जाता है या नहीं, लेकिन मेलिंग सूची पर कुछ डाल सकता है/मामले में किसी मुद्दे को उठाने के लिए देखो। – MrProper

+1

कंपाइलर एक त्रुटि संदेश बताता है कि 'निहित विधि जो भी लागू नहीं है क्योंकि यह आवेदन बिंदु के बाद आता है और इसमें स्पष्ट परिणाम प्रकार नहीं है' इसलिए कम से कम त्रुटि का निदान और ठीक करने के लिए त्रुटि है :) – Hugh

उत्तर

3

त्रुटि संदेश Huw उसकी टिप्पणी में उल्लेख किया है के लिए खोज के बाद, मैं 2010 से इस StackOverflow सवाल ढूँढने में सक्षम था: Why does this explicit call of a Scala method allow it to be implicitly resolved?

यह मैं 2008 में बनाई गई इस स्काला मुद्दे के लिए नेतृत्व किया, और 2011 में बंद कर दिया गया : https://issues.scala-lang.org/browse/SI-801 ('? अंतर्निहित रूपांतरण के लिए स्पष्ट परिणाम प्रकार की आवश्यकता होती है')

मार्टिन ने कहा कि:

मैं प्रति एक से थोड़ा अधिक लागू कर दिया है मिसाइव नियम: स्पष्ट परिणाम प्रकार के बिना एक अंतर्निहित रूपांतरण केवल अपनी परिभाषा के बाद पाठ में दिखाई देता है। इस तरह, हम चक्रीय संदर्भ त्रुटियों से बचते हैं। मैं यह देखने के लिए अभी बंद हूं कि यह कैसे काम करता है। अगर हमें अभी भी समस्याएं हैं तो हम वापस आते हैं।

यह रखती है - अगर मैं फिर से आदेश तोड़ने कोड ताकि साथी वस्तु पहले घोषित किया जाता है, तो कोड संकलित करता है। (यह अभी भी थोड़ा अजीब है!)

(मुझे संदेह है कि मुझे 'लागू नहीं है' अंतर्निहित विधि यहां लागू नहीं है ' संदेश क्योंकि मेरे पास रूपांतरण के बजाय एक निहित मूल्य है - हालांकि मैं यहां मान रहा हूं कि मूल कारण समान है उपरोक्त)।

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

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