2009-04-26 8 views
24

मैंने विशेषज्ञ F # के अच्छे हिस्से के माध्यम से पढ़ा है और एक वास्तविक एप्लिकेशन बनाने पर काम कर रहा हूं। जबकि डीबगिंग, मैं इस तरह FSI आदेशों गुजर बातें repl विंडो में पठनीय बनाने के लिए करने के लिए अभ्यस्त हो गए है:मैं printf का उपयोग कर कस्टम प्रकार के आउटपुट को कैसे अनुकूलित करूं?

fsi.AddPrinter(fun (x : myType) -> myType.ToString()) 

मैं इस विस्तार करने के लिए printf फ़ॉर्मेटर के साथ काम करना चाहते हैं, तो मैं जैसे टाइप कर सकते हैं

printf "%A" instanceOfMyType 

और कस्टम प्रकार के लिए आउटपुट को नियंत्रित करें। पुस्तक का तात्पर्य है कि यह किया जा सकता है (पी 9 3, "जेनेरिक स्ट्रक्चरल स्वरूपण किसी भी उपयोगकर्ता द्वारा परिभाषित डेटा प्रकार, एफ # वेबसाइट पर कवर एक विषय" के साथ काम करने के लिए बढ़ाया जा सकता है), लेकिन मुझे कोई संदर्भ नहीं मिला वास्तव में इसे कैसे पूरा करें। क्या किसी को पता है कि कैसे? क्या यह भी संभव है?

संपादित करें:

मैं एक कोड नमूना शामिल किया जाना चाहिए था, यह एक रिकॉर्ड प्रकार है कि मैं के साथ काम कर रहा हूँ है जैसे

type myType = 
    {a: int}   
    override m.ToString() = "hello" 

let t = {a=5} 
printfn "%A" t 
printfn "%A" (box t) 

दोनों प्रिंट बयान उपज:

{a = 5;} 

उत्तर

34

यह सही तरीका की तरह लग रहा एफ # 2.0 है में यह करने के लिए StructuredFormatDisplay विशेषता का उपयोग, उदाहरण के लिए द्वारा।

यह ऑब्जेक्ट, रिकॉर्ड और यूनियन प्रकारों के लिए समान तरीके से काम करता है।

  1. PropertyName किसी भी प्रकार की संपत्ति हो सकता है: और हालांकि पैटर्न प्रारूप "PreText {PropertyName} PostText" (बहाने और PostText वैकल्पिक जा रहा है) का होना चाहिए, यह वास्तव में से ToString() क्योंकि अधिक शक्तिशाली है। यदि यह एक स्ट्रिंग नहीं है, तो यह संरचित स्वरूपण के अधीन भी होगा। Don Syme's blog इस तरह से एक पेड़ को दोबारा स्वरूपित करने का एक उदाहरण देता है।

  2. यह एक गणना की गई संपत्ति हो सकती है।तो आप वास्तव में हालांकि एक नहीं बल्कि राउंड के बारे में तरह से रिकॉर्ड और संघ प्रकार के लिए काम करने के लिए, ToString() मिल सकता है:

    [<StructuredFormatDisplay("{AsString}")>] 
    type myType = 
        {a: int} 
        override m.ToString() = "hello" 
        member m.AsString = m.ToString() // a property that calls a method 
    

वैसे, ToString() हमेशा इस्तेमाल किया जाएगा (यहां तक ​​कि रिकॉर्ड और संघ प्रकार के लिए) यदि आप printfn "%A" के बजाय printfn "%O" पर कॉल करते हैं।

+0

बीटीडब्ल्यू, इन लिंक को उनके उत्तर में अनुवर्ती टिप्पणी में पोस्ट करने के लिए @Brian को श्रेय दें। मैंने सोचा कि यह देखने वाले किसी और के लिए मांसपेशियों के लायक था। –

4

हम्म ... मैं थोड़ा इस के लिए कुछ परिवर्तन याद है, लेकिन मैं भूल जाते हैं अगर वे पहले या सीटीपी (1.9.6.2) के बाद हुआ।

किसी भी मामले में, CTP पर, मैं

type MyType() = 
    override this.ToString() = "hi" 
let x = new MyType() 
let xs = Array.create 25 x 
printfn "%A" x 
printfn "%A" xs 

जब VFSI खिड़की में मूल्यांकन करता है कि मैं क्या चाहते हैं देखते हैं, और कि

x;; 
xs;; 

भी अच्छी तरह से प्रिंट करता है। तो, मुझे लगता है कि मैं अस्पष्ट हूं कि यह वांछित चीज़ों से अलग कैसे है?

+0

धन्यवाद; मूल पोस्ट में मेरा संपादन देखें, यह एक सदस्य प्रकार के साथ रिकॉर्ड प्रकार है, और वर्ग प्रकार से अलग व्यवहार करता है ... – flatline

+1

@ ब्रायन, हाँ, यह काम करना चाहिए, लेकिन जैसा कि फ्लैटलाइन कहता है, यह संघ के साथ काम नहीं करता है और रिकॉर्ड प्रकार। मैं थोड़ी देर पहले इसमें भाग गया: http://cs.hubfs.net/forums/post/9163.aspx (याद नहीं किया जा सकता है कि अगर मुझे कोई फॉलोअप नहीं मिला तो मुझे fsbugs को कुछ भेजा गया, क्षमा करें) –

+0

यह भी देखें http://blogs.msdn.com/b/dsyme/archive/2010/01/08/some-tips-and-tricks-for-formatting-data-in-f-interactive-and-a-in-sprintf- printf-fprintf.aspx और http://msdn.microsoft.com/en-us/library/ee370334.aspx – Brian

-1

यदि आप ToString विधि को ओवरराइड करते हैं, तो ऐसा करना चाहिए। इस उदाहरण में

[<StructuredFormatDisplay("hello {a}")>] 
type myType = {a: int} 

, डिफ़ॉल्ट {a = 42;} के बजाय, आप hello 42 मिलेगा:

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

  • कोई संबंधित समस्या नहीं^_^