मैं भेदभाव वाले संघ के सदस्य के नामित फ़ील्ड तक कैसे पहुंच सकता हूं?एक्सेस डीयू सदस्य के नामित फ़ील्ड
उदाहरण:
type Point = | Point of x : int * y : int
let p = Point(3, 1)
// how to access x-value or y-value of p here?
मैं भेदभाव वाले संघ के सदस्य के नामित फ़ील्ड तक कैसे पहुंच सकता हूं?एक्सेस डीयू सदस्य के नामित फ़ील्ड
उदाहरण:
type Point = | Point of x : int * y : int
let p = Point(3, 1)
// how to access x-value or y-value of p here?
सामान्य तौर पर, नामित क्षेत्रों के साथ यूनियनों किसी भी अन्य यूनियन प्रकार की तरह काम: आप 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
अपने उदाहरण की तरह एकल मामले भेदभाव यूनियनों के लिए, आप एक match-with
अभिव्यक्ति का उपयोग करने की जरूरत नहीं:
सुपर क्लास में ही केवल संकलक उत्पन्न गुण है।तुम बस ऐसा कर सकता है:
let (Point (x, y)) = p
printf "%i" x // 3
या बस x
हो और उपेक्षा y
रहे हैं:
let (Point (x, _)) = p
printf "%i" x // 3
वहाँ की तरह कुछ प्राप्त करने के लिए किसी भी छोटे वाक्य रचना नहीं है 'जाने p2 = प्वाइंट (px, py)' ? –
सामान्य मामले में, एकाधिक संघ मामलों के साथ: नहीं। 'पी' एक ऑब्जेक्ट हो सकता है जो 'प्वाइंट' केस का प्रतिनिधित्व करता है, लेकिन कुछ अन्य यूनियन केस भी। यदि आप ओओपी शर्तों में इसके बारे में सोचना चाहते हैं: 'पी' सुपरक्लास का एक उदाहरण है, लेकिन आप व्युत्पन्न वर्ग के फ़ील्ड तक पहुंचने का प्रयास कर रहे हैं। 'मैच' कास्ट के बराबर होता है, और खेतों को सुलभ बनाता है। –
@no_mindset, यदि आपके पास केवल एक ही मामला है और आप छोटे वाक्यविन्यास में रुचि रखते हैं, तो यूनियनों के रिकॉर्ड का उपयोग करें। –