2009-04-26 9 views
24

Uzman F # iyi bir yığın aracılığıyla okudum ve gerçek bir uygulama oluşturmak için çalışıyorum. ayıklarken, ben repl penceresinde şeyler okunaklı hale getirmek için bu gibi fsi komutları geçen alışık büyüdüğümüz:Printf kullanarak özel bir türün çıktısını nasıl özelleştiririm?

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

Ben Printf formatlayıcıyla çalışmak için bu uzatmak istiyorum, bu yüzden mesela yazabilirsiniz

printf "%A" instanceOfMyType 

ve özel bir türü için çıkışını kontrol eder. Kitap, bunun yapılabileceğini ima eder (p 93, "Genel yapısal biçimlendirme, herhangi bir kullanıcı tanımlı veri türüyle çalışacak şekilde genişletilebilir, F # web sitesinde bulunan bir konuya ilişkin ), ancak herhangi bir başvuruda bulunamadım. Bunu gerçekten nasıl gerçekleştirebiliriz. Kimse nasıl biliyor mu? Bu mümkün mü?

Düzenleme: Bir kod örneği dahil olması gerekirdi

, ben uğraşıyorum bir kayıt türü örn var

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

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

hem baskı ifadeleri verim:

{a = 5;} 

cevap

34

örneğin StructuredFormatDisplay özelliğini kullanarak F # 2.0 olduğunu bunu yapmanın:

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

Bu örnekte, yerine varsayılan {a = 42;}, sen hello 42 tanınacak.

Bu, nesne, kayıt ve birleştirme türleri için aynı şekilde çalışır.

  1. PropertyName herhangi türde bir özellik olabilir: desen biçiminde "PreText {PropertyName} PostText" (bahanesiyle ve PostText opsiyonel olarak) olmalıdır rağmen, bu aslında daha güçlü ToString() çünkü fazla. Bir dize değilse, o zaman yapılandırılmış biçimlendirmeye tabi olacaktır. Don Syme's blog, bu şekilde bir ağacı yinelenen biçimlendiren bir örnek verir.

  2. Hesaplanan özellik olabilir.Yani aslında rağmen oldukça yuvarlak hakkında şekilde, kayıt ve sendika türlerinin kullanılabilmesi için ToString() alabilir: Bu arada

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

, ToString() daima (hatta kayıt ve sendika türleri için) kullanılacaktır printfn "%A" yerine printfn "%O"'u çağırırsanız.

+0

BTW, bu bağlantıları kendi yanıtına bir takip yorumunda göndermek için @Brian'a kredi. Bakmaya gelen herkes için bir şeyler yapmaya değdiğini düşündüm. –

4

Hmm ... Belli belirsiz bu bazı değişiklikler hatırlama, ancak önce ya CTP (1.9.6.2) sonra oldu ben unutuyorum. Her durumda

, CTP, ben VFSI penceresinde değerlendirilen

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

isteyeyim yapar görüyoruz ve bu

x;; 
xs;; 

da güzel yazdırır. Öyleyse, bunun istenenlerden nasıl farklı olduğunun farkında değil miyim?

+0

Teşekkürler; Düzenlemeyi orijinal gönderiye bakın, üye işlevi eklenmiş bir kayıt türü ve bir sınıf türünden farklı davranır ... – flatline

+1

@Brian, evet, bu işe yaramalı, ancak düz çizgi diyor, birlikle çalışmıyor ve kayıt türleri. Bir süre önce buna rastladım: http://cs.hubfs.net/forums/post/9163.aspx (eğer herhangi bir takip alamadığımda fsbugs'a bir şey gönderdiğimi hatırlayamıyorum) –

+0

Ayrıca bkz. 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 ve http://msdn.microsoft.com/en-us/library/ee370334.aspx – Brian

-1

ToString yöntemini geçersiz kılarsanız, bu yapılmalıdır. Bu Doğru benziyor

İlgili konular