2012-07-04 11 views
6

मैं किताब "व्यावसायिक एफ # 2.0" पढ़ रहा हूँ अशक्त संदर्भ अपवाद रोकूँ लेखक निम्न कोड से पता चलताएफ # विकल्प ... वे वास्तव में

let a string : option = None 
if a.IsNone then 
    System.Console.WriteLine("a is none") 
else 
    System.Console.WriteLine("a is some");; 

तो कहते हैं

"इस उपयोग करता है विकल्प के नल के उपयोग से काफी बेहतर है और रनटाइम पर फेंकने वाले अपवादों के एक महत्वपूर्ण स्रोत को हटाने की दिशा में एक लंबा रास्ता तय करता है "

ठीक है। तो मैं लिखने

System.Console.WriteLine(a.GetType());; 

और मैं

System.NullReferenceException मिल: ऑब्जेक्ट संदर्भ एक वस्तु का एक उदाहरण के लिए सेट नहीं। System.Object.GetType() पर पर। $ FSI_0008.main @()

त्रुटि के कारण बंद कर दिया और मैं 'संयुक्त राष्ट्र की तरह कर रहा हूँ !!! "

कैसे वास्तव में एक

कर रही है
if a.isSome then 
    do bla bla 

any different from 

if a != null then 
    do bla bla 

तो मैं कैसे प्रोग्रामर NullPointers से बचाया जा रहा है नहीं दिख रहा है

पुनश्च:। NullPointerException मुझे अतीत में दु: ख का कारण बना हुआ है बहुत

+4

वह कोड जो आप उस पुस्तक से उद्धृत कर रहे हैं वह खराब शैली है। ऐसा मत करो। 'कोई नहीं' से शून्य संदर्भ अपवाद दुर्भाग्यपूर्ण है। नो-नल का लाभ एफ # के एमएल सबसेट पर लागू होता है जहां यह वास्तव में बहुत मदद करता है। –

उत्तर

4

टॉमस द्वारा जवाब देने के लिए जोड़ने के लिए, Option प्रकार का एक प्रमुख लाभ उच्च आदेश कार्यों है कि यह समर्थन करता है, कि आप और अधिक संक्षिप्तता और सुरक्षा देने में निहित है। आपको उपयोगी विषय पर my blog post मिल सकता है।

9

एफ # कंपाइलर आपको NullReferenceException से पूरी तरह से नहीं रोकता है। जब आप .NET में परिभाषित प्रकारों के साथ काम करते हैं, तो आप अभी भी null मान प्राप्त कर सकते हैं, क्योंकि कोई तरीका नहीं है कि F # इसे रोक सकता है।

हालांकि, जब आप एफ # में घोषित प्रकारों के साथ काम करते हैं, तो संकलक उस प्रकार के null मूल्यों को बनाने की अनुमति नहीं देता है, और इसलिए यह उस मामले में NullReferenceException से बचाता है। उदाहरण के लिए, निम्नलिखित कोड संकलन नहीं करता है:

type Person(name:string) = 
    member x.Name = name 

// 'Person' is a type declared in F#, so the argument cannot be 'null' in safe code 
let printName (person:Person) = 
    printfn "%s" person.Name 

// Compiler error here - 'null' is not a valid value of 'Pereson' type 
printName null 

जब आप एक तर्क के रूप option<Person> उपयोग करते हैं, तो आप स्पष्ट रूप से None और Some मामलों की जांच करने के लिए है। यह match का उपयोग करके सबसे अच्छा किया जाता है, जो जांचता है कि आप किसी भी मामले में अनुपलब्ध नहीं हैं। उदाहरण के लिए:

let printName (person:option<Person>) = 
    match person with 
    // You get a warning here, saying that you're not handling the 'None' case! 
    | Some person -> printfn "%s" person.Name 

चेतावनी आपको बताती है कि आपको केस हैंडलिंग None जोड़ना चाहिए। आप अभी भी कोड संकलित कर सकते हैं, लेकिन अगर आप चेतावनियों को अनदेखा नहीं करते हैं तो आपको F # प्रकारों के साथ काम करते समय NullReferenceException नहीं मिलेगा।

this great, related StackOverflow post भी देखें।

+0

"जब आप एफ # में घोषित प्रकारों के साथ काम करते हैं, तो संकलक उस प्रकार के शून्य मान बनाने की अनुमति नहीं देता है"।प्रश्न में counterexample 'none' शामिल है जो कि F # प्रकार का मान है जिसे 'शून्य' के रूप में दर्शाया गया है। –

+0

@ जोनह्रोप - यह एक कोने का मामला है, हालांकि, प्रतिनिधित्व आमतौर पर केवल 'ऑब्जेक्ट' पर परिभाषित .NET विधियों को कॉल करके मनाया जाता है। उदाहरण के लिए, 'none.IsNone' को कॉल करने से' NullReferenceException' नहीं फेंकता है। – kvb

+0

@ जोनह्रोप यह सच नहीं है। भाषा परिप्रेक्ष्य से, 'विकल्प <'T>' 'null' को मान के रूप में अनुमति नहीं देता है (कोशिश करें 'ए (विकल्प ) = null')। संकलित प्रतिनिधित्व एक अलग बात है, लेकिन यह केवल इंटरऑप के लिए महत्वपूर्ण है। –

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