我已经阅读了大量的 Expert 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"
(PreText 和 PostText 是可选的),这实际上比 ToString()
更强大因为:PropertyName
可以是任何类型的属性。如果它不是字符串,那么它也将受到结构化格式的约束。 Don Syme's blog给出了以这种方式递归格式化树的示例。 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"
.
关于f# - 如何使用 printf 自定义自定义类型的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/791706/