سؤال

لقد قرأت من خلال قطعة جيدة من خبير f # وأنا أعمل على بناء تطبيق حقيقي. أثناء تصحيح الأخطاء، لقد اعتادت اعتاد على اجتياز أوامر FSI مثل هذا لجعل الأمور مقروءة في نافذة التشغيل:

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

أرغب في تمديد هذا للعمل مع فورقة Printf، لذلك يمكنني الكتابة على سبيل المثال

printf "%A" instanceOfMyType 

والتحكم في الإخراج لنوع مخصص. يتضمن الكتاب أنه يمكن القيام بذلك (P 93، "يمكن تمديد التنسيق الهيكلية العامة للعمل مع أي أنواع بيانات محددة من قبل المستخدم، وهو موضوع مغطى على موقع F #)، لكنني فشلت في العثور على أي مراجع حول كيف لإنجاز هذا بالفعل. هل يعرف أحد كيف؟ هل هو ممكن؟

يحرر:

يجب أن تضمنت عينة رمز، إنها نوع قياسي أتعامل معه، على سبيل المثال

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

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

كل من بيانات الطباعة العائد:

{a = 5;}
هل كانت مفيدة؟

المحلول

يبدو أن الطريقة الصحيحة للقيام بذلك في F # 2.0 هي باستخدام StructuredFormatDisplay السمة، على سبيل المثال:

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

في هذا المثال، بدلا من الافتراضي {a = 42;}, ، سوف تحصل hello 42.

هذا يعمل بنفس الطريقة لأنواع الكائن والسجل والاتحاد. وعلى الرغم من أن النمط يجب أن يكون بالتنسيق "PreText {PropertyName} PostText" (ذريعة و poststext. كونها اختيارية)، هذا هو في الواقع أقوى من ToString() لأن:

  1. PropertyName يمكن أن تكون خاصية من أي نوع. إذا لم تكن سلسلة، فسيخضع أيضا للتنسيق المنظم. دون سيم بلوق يعطي مثالا على تنسيق شجرة متكررة بهذه الطريقة.

  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 "%O" بدلا من printfn "%A".

نصائح أخرى

HMM ... أنا أذكر غامضة بعض التغييرات في هذا، لكنني نسيت إذا حدثت قبل أو بعد CTP (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;;

يطبع أيضا بشكل جيد. لذلك، أعتقد أنني غير واضح كيف يختلف هذا عن ما هو مطلوب؟

إذا تجاوزت طريقة ToString، يجب القيام بذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top