2013-08-08 6 views
7

मैं एफ # में इस सी # के बराबर लिखना चाहते हैं:सार्वजनिक क्षेत्रों के साथ एक अपरिवर्तनीय संरचना कैसे घोषित करें?

struct Vector2 { 
    public readonly int X; 
    public readonly int Y; 
    public Vector2(int x, int y) { 
     X = x; 
     Y = y; 
    } 
} 

इस उपयोगकर्ता बलों एक उदाहरण बनाने के लिए तर्क की आपूर्ति करने [संपादित करें: यह मान प्रकार के लिए गलत है - सभी मूल्य प्रकार एक डिफ़ॉल्ट निर्माता है] । एक डिफ़ॉल्ट वेक्टर 2 को एक स्थिर रीडोनली फ़ील्ड के साथ भी प्रदान किया जा सकता है, यानी वेक्टर 2.जेरो।

यह एक ही रास्ता सार्वजनिक क्षेत्रों पाने के लिए की तरह लग रहा "वैल" कीवर्ड के माध्यम से है, लेकिन मुझे उन्हें डिफ़ॉल्ट निर्माता के साथ प्रारंभ करने देने के लिए प्रतीत नहीं होता है, और मैं दो कंस्ट्रक्टर्स है नहीं करना चाहती:

[<Struct>] 
    type MyInt(value) = 
     val public Value : int = value;; 

      val public Value : int = value;; 
    -------------------------------^ 

stdin(7,32): error FS0010: Unexpected symbol '=' in member definition 

मुझे पता है कि यह सदस्य बाइंडिंग के साथ किया जा सकता है लेकिन यह गुणों को बनाता है, फ़ील्ड नहीं, अगर मैं अच्छी तरह समझता हूं।

उत्तर

5

इस http://msdn.microsoft.com/en-us/library/vstudio/dd233233(v=vs.120).aspx के अनुसार, कि

type Vector2 = 
    struct 
     val public X: int 
     val public Y: int 
     new(x: int, y: int) = { X = x; Y = y } 
    end 
+0

दुर्भाग्य से यह मुझे पैरामीटर पास किए बिना वेक्टर बनाने देता है, जैसे: 'v = Vector2() '। यह नहीं कि यह एक बहुत ही गंभीर समस्या है, लेकिन मैं अभी भी सोच रहा हूं कि यह डिफ़ॉल्ट खाली कन्स्ट्रक्टर के बिना किया जा सकता है या नहीं। – Asik

+5

@Aसिक: यह आपके सी # कोड के बारे में भी सच है - यह एक सीएलआर सीमा है, एफ # सीमा नहीं। – ildjarn

+1

"स्ट्रक्चर के पास कोई तर्क नहीं होने पर ऑब्जेक्ट कन्स्ट्रक्टर नहीं हो सकता है। यह सभी सीएलआई भाषाओं पर लगाया गया प्रतिबंध है क्योंकि structs स्वचालित रूप से डिफ़ॉल्ट कन्स्ट्रक्टर का समर्थन करते हैं।" - यह संकलक कहता है, इसलिए आप जो भी चाहते हैं उसे हमेशा प्राप्त नहीं कर सकते ... –

2

के रूप में किया जा सकता है एक एफ # Record आप के लिए काम करेंगे, तो यह काम करेगा:

type MyInt = { 
    Value: int 
};; 

फिर प्रारंभ करने में:

let i = {Value=1};; 

चूंकि मुझे आपके उपयोग के मामले की पूरी तरह से यकीन नहीं है, मुझे यकीन नहीं है कि यह कितना उपयोगी है है।

संपादित करें: इसके लिए क्या मूल्य है, यदि मूल्य मान को प्राथमिकता देने का आपका कारण यह है कि आप मूल्य प्रकार समानता अर्थशास्त्र चाहते हैं, तो रिकॉर्ड समर्थन करते हैं (भले ही वे संदर्भ प्रकार हैं)। इस पर विचार करें:

type Vector2 = { 
    X:int; 
    Y:int 
};; 

type Vector2 = 
    {X: int; 
    Y: int;} 

let v = {X=1;Y=1};; 

val v : Vector2 = {X = 1; 
        Y = 1;} 

let v2 = {X=1;Y=1};; 

val v2 : Vector2 = {X = 1; 
        Y = 1;} 

v = v2;; 
val it : bool = true 

let v3 = {X=2;Y=2};; 
v = v3;; 
val it: bool = false 

मैं कहना है भले ही रिकॉर्ड संदर्भ प्रकार के होते हैं, कारण है कि लोगों को मूल्य प्रकार (समानता अर्थ विज्ञान) का उपयोग से एक रिकॉर्ड के साथ एक समस्या नहीं है कि मतलब है। भले ही यह एक संदर्भ प्रकार है, मेरा मानना ​​है कि यह उस सी # कोड के व्यवहार के बहुत करीब है जिसे आप अनुकरण करने की कोशिश कर रहे हैं - इसके लिए क्या लायक है।

+0

रिकॉर्ड के साथ समस्या यह है कि वे गुणों के साथ संदर्भ प्रकार के रूप में लागू किए गए हैं और यहां मैं फ़ील्ड के साथ एक मान प्रकार प्राप्त करने का प्रयास कर रहा हूं। – Asik

+0

दोबारा - अपने उपयोग के मामले को नहीं जानते हैं, भले ही रिकॉर्ड संदर्भ प्रकार हैं, उनके पास मूल्य प्रकार समानता अर्थशास्त्र है। मैंने थोड़ा सा जवाब देने के लिए अपना जवाब संपादित कर लिया है। –

+0

मेरे पास वास्तव में उपयोग का मामला नहीं है, मैं बस यह समझने की कोशिश कर रहा था कि सार्वजनिक अपरिवर्तनीय फ़ील्ड (सीएलआर अर्थ में) के साथ मूल्य प्रकार कैसे बनाएं और डिफ़ॉल्ट कन्स्ट्रक्टर से बचें। यद्यपि आपकी व्याख्या के लिए धन्यवाद। – Asik

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