2013-08-28 6 views
6

स्कैला कंपाइलर में -Xcheck-null है जो यह जांचने का प्रयास करता है कि रनटाइम में कोई संभावित शून्य सूचकता है या नहीं।मार्क विधि कॉल करें कि यह हमेशा नल परिणाम नहीं देता

यह मेरे लिए ठीक है, लेकिन मैं बहुत अधिक झूठे सकारात्मक मिलता है, अर्थात लगता है मुझे लकड़हारा को परिभाषित:

private final val LOGGER: Logger = LoggerFactory.getLogger(classOf[GenericRestImpl]) 

विधि getLogger रिटर्न कभी नहीं null। मैं इस ज्ञान को कंपाइलर को कैसे पास कर सकता हूं ताकि शिकायत न हो?

[WARNING] TestImpl.scala:31: warning: potential null pointer dereference: LOGGER.debug 
[WARNING]  LOGGER.debug("Using {} for sort", sortParam) 

जब मैं नया उदाहरण बनाने मैं इसे NotNull विशेषता के साथ चिह्नित कर सकते हैं:

return new Foo() with NotNull. 

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

मैंने प्रश्न Library support for Scala's NotNull trait पर भी प्रश्न की जांच की लेकिन यह मेरी समस्या को हल करने में मदद नहीं की।

+0

आप सही समझते हैं, NotNull विशेषता सिर्फ एक मार्कर है। यह और कुछ नहीं करता है। – Jatin

उत्तर

5

जतिन का उल्लेख के रूप में, NotNull एक डाली अपने आधार प्रकार with NotNull

तो तुम जैसे कुछ लिख सकते हैं के लिए मजबूर करने के लिए है, ताकि आप NotNull उपयोग कर सकते हैं कुछ भी टैग करने के लिए, बस एक मार्कर या टैग है। ऐसा करने के लिए चाल यह "notnull".asInstanceOf[String with NotNull]। यदि आप सुनिश्चित हैं कि यह कभी भी शून्य नहीं है तो यह एक सुरक्षित कलाकार है।

अपने वास्तविक उदाहरण में, आप इसलिए लिख सकते हैं:

private final val LOGGER: Logger with NotNull = 
    LoggerFactory.getLogger(classOf[GenericRestImpl]).asInstanceOf[Logger with NotNull] 

हालांकि इस के लिए नए प्रकार बनाने के लिए कोई जरूरत नहीं है, यह थोड़ा बोझिल है आप इसे एक बहुत कुछ किया है, तो आप कुछ इस्तेमाल कर सकते हैं थोड़ा utils सरल करने के लिए/अंकन स्पष्ट:

type NeverNull[T] = T with NotNull 
def neverNull[A](a: A): NeverNull[A] = a.asInstanceOf[A with NotNull] 

NeverNull बस किसी भी प्रकार TNotNull और neverNull के साथ टैग के लिए एक उपनाम है कभी नहीं अशक्त होने के रूप में प्रकार A के किसी भी मौजूदा मूल्य टैग करने के लिए एक छोटे से आवरण है।

फिर आप उपयोग कर सकते हैं के रूप में:

implicit def neverNull[A](a: A): NeverNull[A] = a.asInstanceOf[A with NotNull] 

private final val LOGGER: NeverNull[Logger] = LoggerFactory.getLogger(classOf[GenericRestImpl]) 

ध्यान दें कि NeverNull[Logger] अभी भी है:

private final val LOGGER: NeverNull[Logger] = neverNull { 
     LoggerFactory.getLogger(classOf[GenericRestImpl]) 
} 

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

निर्माण इस प्रकार का एक अनबॉक्स्ड में चिह्नित प्रकार कहा जाता है और बहुत उपयोगी है, अन्य अनुप्रयोगों और चर्चा here और here देख रहा है।

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