Frage

Ich habe durch ein gutes Stück von lesen Expert F # und arbeite eine tatsächliche Anwendung auf den Aufbau. Während des Debuggens habe ich vorbei fsi Befehle wie diese daran gewöhnt, Dinge lesbar im ers Fenster zu machen:

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

Ich möchte dies erweitern mit dem printf Formatierungsprogramm zu arbeiten, so konnte ich beispiel geben.

printf "%A" instanceOfMyType 

und die Ausgabe für einen benutzerdefinierten Typen steuern. Das Buch setzt voraus, dass diese (S. 93 getan werden kann, „Generic Struktur Formatierung erweitert werden kann mit beliebigen benutzerdefinierten Datentypen zu arbeiten, ein Thema auf der F # Website "genannt), aber ich habe versagen alle Verweise zu finden, wie zu dies tatsächlich zu erreichen. Wer weiß, wie? Ist es überhaupt möglich?

Edit:

Ich sollte ein Codebeispiel enthalten sind, ist es eine Satzart, die ich mit zu tun habe, z.

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

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

beide Druck Aussagen ergeben:

{a = 5;}
War es hilfreich?

Lösung

Es ist wie der richtige Weg sieht diese 2.0 in F # zu tun ist, mithilfe des StructuredFormatDisplay Attribut, zum Beispiel:

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

In diesem Beispiel wird anstelle des Standard-{a = 42;}, würden Sie hello 42 erhalten.

Dies funktioniert auf die gleiche Art und Weise für das Objekt, aufnehmen und Union-Typen. Und obwohl muss das Muster des Formats "PreText {PropertyName} PostText" sein ( PRETEXT und PostText ist optional), ist dies tatsächlich mächtiger als ToString() weil:

  1. PropertyName kann eine Eigenschaft von jeder Art sein. Wenn es nicht ein String ist, dann wird es auch für strukturierte Formatierung unterliegen. Don Syme Blog gibt ein Beispiel rekursiv einen Baum auf diese Weise zu formatieren.

  2. Es kann eine berechnete Eigenschaft sein. So könnten Sie tatsächlich bekommen ToString() für die Aufzeichnung und Union-Typen zu arbeiten, wenn auch in eher Umwegen:

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

Durch die Art und Weise, ToString() wird immer dann verwendet werden (auch für die Aufzeichnung und Union-Typen), wenn Sie printfn "%O" rufen statt printfn "%A".

Andere Tipps

Hmm ... Ich erinnere mich vage, einige Änderungen, aber ich vergessen, wenn sie vor oder nach dem CTP (1.9.6.2) passiert ist.

Auf jedem Fall auf der CTP, ich sehe, dass

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

, wenn im VFSI Fenster ausgewertet tut, was ich möchte, und dass

x;;
xs;;

druckt auch schön. Also, ich denke, ich bin unklar, wie dies von dem abweicht, was gewünscht wird?

Wenn Sie ToString-Methode außer Kraft setzen, sollte das tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top