如何使用 printf 自定义自定义类型的输出? [英] How do I customize output of a custom type using printf?

查看:57
本文介绍了如何使用 printf 自定义自定义类型的输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了大量Expert F# 并且正在努力构建一个实际的应用程序.在调试时,我已经习惯于传递这样的 fsi 命令以使 repl 窗口中的内容清晰可见:

I've read through a good chunk of Expert F# and am working on building an actual application. While debugging, I've grown accustomed to passing fsi commands like this to make things legible in the repl window:

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

我想扩展它以使用 printf 格式化程序,所以我可以输入例如

I would like to extend this to work with the printf formatter, so I could type e.g.

printf "%A" instanceOfMyType 

并控制自定义类型的输出.这本书暗示可以做到这一点(第 93 页,通用结构格式可以扩展为使用任何用户定义的数据类型,F# 网站上涵盖的主题"),但我没有找到有关如何实际完成此操作的任何参考资料.有谁知道如何?甚至可能吗?

and control the output for a custom type. The book implies that this can be done (p 93, "Generic structural formatting can be extended to work with any user-defined data types, a topic covered on the F# website"), but I have failed to find any references as to how to actually accomplish this. Does anyone know how? Is it even possible?

我应该包含一个代码示例,它是我正在处理的记录类型,例如

I should have included a code sample, it's a record type that I'm dealing with, e.g.

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 属性,例如:

It looks like the Right Way to do this in F# 2.0 is by using the StructuredFormatDisplay attribute, for example:

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

在这个例子中,你会得到 hello 42 而不是默认的 {a = 42;}.

In this example, instead of the default {a = 42;}, you would get hello 42.

这对于对象、记录和联合类型的工作方式相同.虽然模式必须是 "PreText {PropertyName} PostText" 格式(PreTextPostText 是可选的),这实际上更强大比 ToString() 因为:

This works the same way for object, record, and union types. And although the pattern must be of the format "PreText {PropertyName} PostText" (PreText and PostText being optional), this is actually more powerful than ToString() because:

  1. PropertyName 可以是任何类型的属性.如果它不是字符串,那么它也将受到结构化格式的约束.Don Syme 的博客 给出了以这种方式递归格式化树的示例.

  1. PropertyName can be a property of any type. If it is not a string, then it will also be subject to structured formatting. Don Syme's blog gives an example of recursively formatting a tree in this way.

它可能是一个计算属性.所以你实际上可以让 ToString() 为记录和联合类型工作,尽管以一种相当迂回的方式:

It may be a calculated property. So you could actually get ToString() to work for record and union types, though in a rather round-about way:

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

顺便说一句,如果您调用 printfn "%O" 而不是 printfn,将始终使用 ToString()(即使对于记录和联合类型)"%A".

By the way, ToString() will always be used (even for record and union types) if you call printfn "%O" instead of printfn "%A".

这篇关于如何使用 printf 自定义自定义类型的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆