2017-03-08 8 views

उत्तर

4

सामान्य तौर पर, नामित क्षेत्रों के साथ यूनियनों किसी भी अन्य यूनियन प्रकार की तरह काम: आप match के माध्यम से खेतों तक पहुँच जाएगा:

let x, y = 
    match p with 
    | Point (x1, y1) -> x1, y1 

The F# documentation भी मिलान करने का एक तरीका का उल्लेख है केवल कुछ नामित पैरामीटर। आपके मामले में, यह मतलब है कि आप लिख सकते हैं:

let xOnly = 
    match p with 
    | Point (x = x1) -> x1 

यदि आप केवल इतना है एक भी मामला है, @ p.s.w.g द्वारा उत्तर देखें। उस उत्तर में कोड सभी भेदभाव वाले संघों के लिए सामान्य है। नामित क्षेत्रों के साथ सिंगलटन यूनियनों के लिए, आप विशेष सिंटेक्स ऊपर दिखाए गए का उपयोग करें और लिख सकते हैं:

let Point(x = myX) = p 

यह myX के क्षेत्र x का मूल्य बांधता है।

पीएस टिप्पणियों के अनुसार: p.x करके आप तुरंत फ़ील्ड क्यों नहीं पढ़ सकते हैं? आप एक छोटे से ऑब्जेक्ट पदानुक्रम के रूप में एक भेदभाव संघ के बारे में सोच सकते हैं (और इसका उपयोग करें, discriminated union documentation देखें: "आप अक्सर एक छोटे से ऑब्जेक्ट पदानुक्रम के लिए एक वैकल्पिक विकल्प के रूप में एक भेदभाव संघ का उपयोग कर सकते हैं")। पर विचार करें निम्नलिखित ड्यू:

type Shape = | Circle of r: float | Square of float 

आप सुपर क्लास के रूप में Shape देख सकते हैं। Circle और Square दो व्युत्पन्न कक्षाएं हैं, जिनमें प्रत्येक एक float संपत्ति है। आपके द्वारा बनाए गए Circle या Square का प्रत्येक उदाहरण Shape होने के लिए उभरा होगा।

इसके साथ, यह स्पष्ट हो जाता है कि आप तुरंत खेतों को क्यों नहीं पढ़ सकते हैं: आपको सबसे पहले यह निर्धारित करने की आवश्यकता है कि आप किस व्युत्पन्न कक्षाओं को देख रहे हैं, केवल सही उप-वर्ग में डालने के बाद आप खेतों को पढ़ सकते हैं ।

इस वस्तु पदानुक्रम दृश्य कैसे दस एफ # द्वारा आंतरिक रूप से नियंत्रित किया जाता है करने के लिए बहुत बारीकी से मेल खाता है:

> typeof<Shape>.GetNestedTypes() 
|> Seq.iter (fun t -> 
    let p = t.GetProperties() 
    let s = 
     p 
     |> Array.map (fun p -> sprintf "%s: %s" p.Name p.PropertyType.Name) 
     |> String.concat "; " 
    printfn "Nested type %s: %i Properties %s" t.Name p.Length s 
);; 
Nested type Tags: 0 Properties 
Nested type Circle: 4 Properties r: Double; Tag: Int32; IsCircle: Boolean; IsSquare: Boolean 
Nested type Square: 4 Properties Item: Double; Tag: Int32; IsCircle: Boolean; IsSquare: Boolean 
: आप प्रतिबिंब में ड्यू प्रकार को देखें, तो आप दो नेस्टेड प्रकार अपने संघ मामलों के रूप में एक ही नाम है कि देखेंगे

वास्तविक डेटा उपclass के गुणों में रहता है। Circle के लिए, हमने नाम फ़ील्ड का उपयोग किया, आप संपत्ति r देखते हैं। Square के लिए, हमारे पास Item संपत्ति (या Item1, Item2 में कई तर्क थे) में डेटा है। बाकी संकलक उत्पन्न होते हैं: संख्यात्मक Tag फ़ील्ड जिसका उपयोग उप-वर्गों के बीच जल्दी से अंतर करने के लिए किया जाएगा, और उप-वर्ग जांच के लिए दो बूल गुण।

>  typeof<Shape>.GetProperties() 
    |> Seq.iter (fun p -> printfn "Property %s" p.Name);; 
Property Tag 
Property IsCircle 
Property IsSquare 
+0

वहाँ की तरह कुछ प्राप्त करने के लिए किसी भी छोटे वाक्य रचना नहीं है 'जाने p2 = प्वाइंट (px, py)' ? –

+1

सामान्य मामले में, एकाधिक संघ मामलों के साथ: नहीं। 'पी' एक ऑब्जेक्ट हो सकता है जो 'प्वाइंट' केस का प्रतिनिधित्व करता है, लेकिन कुछ अन्य यूनियन केस भी। यदि आप ओओपी शर्तों में इसके बारे में सोचना चाहते हैं: 'पी' सुपरक्लास का एक उदाहरण है, लेकिन आप व्युत्पन्न वर्ग के फ़ील्ड तक पहुंचने का प्रयास कर रहे हैं। 'मैच' कास्ट के बराबर होता है, और खेतों को सुलभ बनाता है। –

+1

@no_mindset, यदि आपके पास केवल एक ही मामला है और आप छोटे वाक्यविन्यास में रुचि रखते हैं, तो यूनियनों के रिकॉर्ड का उपयोग करें। –

5

अपने उदाहरण की तरह एकल मामले भेदभाव यूनियनों के लिए, आप एक match-with अभिव्यक्ति का उपयोग करने की जरूरत नहीं:

सुपर क्लास में ही केवल संकलक उत्पन्न गुण है।तुम बस ऐसा कर सकता है:

let (Point (x, y)) = p 
printf "%i" x // 3 

या बस x हो और उपेक्षा y रहे हैं:

let (Point (x, _)) = p 
printf "%i" x // 3 
संबंधित मुद्दे