我怎么定义输出的一个自定义的类型使用printf?
-
16-09-2019 - |
题
我读过一块好的 专家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()
因为:
PropertyName
可以是财产的任何类型。如果它不是一个弦,然后,它也将受到结构化格式。 别赛姆博客 给一个例子递归的格式一棵树在这种方式。它可能是计算财产。所以你其实可以获得
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方法,应该这样做。