我读过一块好的 专家F# 和我的工作上建立一个实际应用。在调试,我已经习惯于传递fsi命令这样做的东西清晰易读的repl窗口:

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

我想延长这项工作与printf格式,这样我就可以型例如

printf "%A" instanceOfMyType 

并控制输出用于一个自定义的类型。该书意味着可以这样做(第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" (借口PostText 被选),这实际上是比更强大 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".

其他提示

嗯...我依稀记得一些变化,但我忘了,如果他们之前或之后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