2009-11-17 2 views
34

क्या यह चीजों को थोड़ा अधिक कुशल बनाने के लिए है (प्रमोमर के लिए): मुझे लगता है कि Some में चीजों को लपेटने के लिए थोड़ा मुश्किल हो जाता है, उदाहरण के लिए Some(5)। क्या कुछ इस तरह के बारे में:टी से विकल्प [टी] में एक अंतर्निहित रूपांतरण को स्केल में जोड़ा/बनाया जाना चाहिए?

implicit def T2OptionT(x : T) : Option[T] = if (x == null) None else Some(x) 

उत्तर

30

आप कुछ प्रकार की सुरक्षा खो देंगे और संभवतः भ्रम पैदा करेंगे। उदाहरण के लिए:

val iThinkThisIsAList = 2 
    for (i <- iThinkThisIsAList) yield { i + 1 } 

मैं (जो भी कारण के लिए) सोचा था कि मैं एक सूची थी, और यह संकलक द्वारा पकड़े नहीं था, जब मैं इस पर दोहराया है क्योंकि यह एक विकल्प के लिए स्वतः बदल दिया गया था [इंट] ।

मुझे यह जोड़ना चाहिए कि मुझे लगता है कि यह स्पष्ट रूप से आयात करने के लिए एक महान निहित है, शायद वैश्विक डिफ़ॉल्ट नहीं।

+0

कम से कम इंटेलिजे आईडीईए में मैं देख सकता हूं कि कुछ ऑटो-रूपांतरित हो जाता है (डिफ़ॉल्ट रूप से इसे रेखांकित किया जाता है)। लेकिन शायद यह निर्दिष्ट करने का एक तरीका होना चाहिए कि किसी विधि को मूल्य पारित करते समय एक अंतर्निहित रूपांतरण केवल तभी होना चाहिए, जब उस पर कोई विधि कॉल न हो। – herman

1

यह प्रतीत होता है कि यह अन्य डेवलपर्स आप भ्रमित हो सकते हैं, क्योंकि वे अपने कोड को पढ़ने के लिए।

आम तौर पर, ऐसा लगता है, implicit दूसरे करने के लिए एक वस्तु से डाली मदद करने के लिए, भ्रामक कास्टिंग कोड है कि कोड को अस्त-व्यस्त कर सकते हैं बाहर कटौती करने के लिए अगर मैं कुछ चर है और यह किसी भी तरह एक Some तो हो जाता है कि होने के लिए प्रतीत होता है काम करता है, लेकिन, कष्टप्रद।

आप यह देखने के लिए कुछ कोड डालना चाहते हैं कि यह कितना भ्रमित हो रहा है।

+1

मैं अपने बहाव मिलता है .. हालांकि, विकल्प की बात [टी] कि यह एक मूल्य या कोई नहीं पकड़ सकता है, इसलिए इसे करने के लिए सहज ज्ञान युक्त लगता है मुझे लगता है कि यदि कोई विधि प्रकार का एक चर लेता है विकल्प [टी] मैं इसमें टी को पारित करने में सक्षम होना चाहिए। क्या आप एक उदाहरण के बारे में सोच सकते हैं जहां आपको कुछ भ्रम हो सकता है, उदा। एक परिवर्तनीय कुछ अनजाने में बन रहा है? –

-2

यह मेरे लिए अच्छा लग रहा है, सिवाय इसके कि यह एक आदिम टी (जो शून्य नहीं हो सकता) के लिए काम नहीं कर सकता है। मुझे लगता है कि एक गैर विशिष्ट जेनेरिक हमेशा बॉक्सिंग प्राइमेटिव हो जाता है, तो शायद यह ठीक है।

25

ध्यान दें कि आप explicit implicit पैटर्न का उपयोग कर सकते हैं जो भ्रम से बचें और एक ही समय में कोड terse रखें।

मैं स्पष्ट अंतर्निहित से क्या मतलब बजाय Option[T] को T से एक प्रत्यक्ष रूपांतरण है आप एक आवरण वस्तु जो T से Option[T] करने के लिए रूपांतरण करने के लिए साधन प्रदान करता है के लिए एक रूपांतरण हो सकता है।

class Optionable[T <: AnyRef](value: T) { 
    def toOption: Option[T] = if (value == null) None else Some(value) 
} 

implicit def anyRefToOptionable[T <: AnyRef](value: T) = new Optionable(value) 

... मैं Optionable की तुलना में यह करने के लिए एक बेहतर नाम मिल सकती है, लेकिन अब आप कोड लिख सकते हैं जैसे:

val x: String = "foo" 
x.toOption // Some("foo") 

val y: String = null 
x.toOption // None 

मुझे विश्वास है कि इस तरह से पूरी तरह से पारदर्शी है और की समझ में एड्स लिखित कोड - एक अच्छे तरीके से शून्य के लिए सभी चेक को खत्म करना।

T <: AnyRef पर ध्यान दें - आपको केवल उन उदाहरणों के लिए यह निहित रूपांतरण करना चाहिए जो null मानों को अनुमति देते हैं, जो परिभाषा संदर्भ प्रकार हैं।

+0

हाय फ्लवी, दिलचस्प सुझाव। मुझे यह समग्र रूप से पसंद है - हालांकि मुझे लगता है कि यह मेरी समस्या को और भी बेहतर नहीं बनाता है, अब कुछ टाइप करने के बजाय() मुझे टूशन टाइप करना होगा ... लेकिन इसमें शून्य के साथ काम करने का लाभ है। –

+6

'विकल्प (x)' ('कुछ (x)' के बजाय) शून्य के साथ भी काम करता है। – schmmd

+2

@ flaviu-cipcigan, वही करता है लेकिन कम - निहित वर्ग IntWithTimes [टी] (x: टी) { अप टू अप विकल्प: विकल्प [टी] = अगर (x! = Null) विकल्प (x) अन्य कोई नहीं } – Maxim

11

अंतर्निहित रूपांतरण के लिए सामान्य दिशा निर्देशों इस प्रकार हैं:

  • जब आप किसी प्रकार के सदस्यों को जोड़ने की जरूरत है (एक ला "खुला वर्गों", उर्फ ​​पैटर्न "मेरी लाइब्रेरी दलाल"), एक में बदलने का नया प्रकार जो AnyRef बढ़ाता है और जो केवल आपको आवश्यक सदस्यों को परिभाषित करता है।
  • जब आपको विरासत पदानुक्रम को "सही" करने की आवश्यकता होती है।इस प्रकार, आपके पास कुछ प्रकार A है जो उप-वर्गीकृत B होना चाहिए, लेकिन किसी कारण से नहीं किया गया था। उस स्थिति में, आप A से B पर एक अंतर्निहित रूपांतरण परिभाषित कर सकते हैं।

ये केवल मामले हैं जहां यह एक अंतर्निहित रूपांतरण को परिभाषित करने के लिए उचित है। कोई अन्य रूपांतरण जल्दबाजी में सुरक्षा और शुद्धता के मुद्दों में चलाता है।

यह वास्तव में T के लिए Option[T] का विस्तार करने के लिए कोई समझ नहीं लेता है, और स्पष्ट रूप से रूपांतरण का उद्देश्य सदस्यों के अतिरिक्त नहीं है। इस प्रकार, ऐसा रूपांतरण अव्यवस्थित होगा।

0

तुम भी विधि को ओवरलोड की कोशिश कर सकते:

def having(key:String) = having(key, None) 

def having(key:String, default:String) = having(key, Some(default)) 

def having(key: String, default: Option[String]=Option.empty) : Create = { 
    keys += ((key, default)) 
    this 
}