F# Interactive技巧:在sprintf/printf/fprintf中使用AddPrinter,addPrintTransformer和%A来格式化数据
2011-12-31 10:35
537 查看
Mingtian Ni 问过这样的一个问题:
我想改变一些类型在fsi输出中的格式,尤其是集合类型。怎样的方法才是比较合理的呢?….有哪位朋友可以提供一点信息吗? 或者一些指南和示例那就更好了。
下面就是一些在F#Interactive中格式化数据的技巧。 这并不足以理解为一个指南,这仅仅能帮你入门。如果你需要更多的示例,请联系我。
对F# interactive来说,一个简单的方法就是使用fsi.AddPrintTransformer来生成一个显示对象的替代品(或者使用更小的、产生一个字符串的fsi.AddPrinter函数),例如:
type C(elems:int list) =
member x.Contents = elems
member x.IsBig = elems.Length > 100
let c = C [1;2;3]
fsi.AddPrintTransformer (fun (c:C)-> box c.Contents)
产生:
val c : C = [1; 2; 3]
AddprintTransformer有一点很好,你可以让它成为有条件的——返回null 来表明formatter(用来格式化的一串字符)应该被忽略:
fsi.AddPrintTransformer (fun (c:C)->
if c.IsBig then
null else box c.Contents)
有一点非常好,如果你将它和“obj”类型一起使用,你可以对任意的对象作特定的格式化:
fsi.AddPrintTransformer (fun (obj:obj)->
match obj with :? C
as c -> box c.Contents | _->
null)
这里有一个问题,fsi.AddPrinter和fsi.AddPrintTransformer不会更改位于sprintf、printf等函数中的%A的行为。对于那些设置一个简单标志(即命名一个成员属性产生一个代理对象)而受限制的类型,以及一些周围的文字:
[<StructuredFormatDisplayAttribute("CCC {Contents}")>]
type C(elems:int list) =
member x.Contents = elems
let c = C [1;2;3]
产生:
val c : C = CCC [1; 2; 3]
如果你的类型是一个普通的集合类, 那么使用一个list 或者sequence 作为这个替代对象。
如果你的类型是一个matirx或者table 类型,那么使用一个2D array作为这个替代对象。
如果你的类型在逻辑上说是一个union 类型,但你已经隐藏了其背后的抽象边界的表现形式,那么可以考虑使用一个独立的、能够解开你的对象的结构的helper union 类型(如:如果你的类型是一个递归类型,那么可以解开它的第一层)
如果你的数据是递归树型的,你可以描述它的子树为一个list:
[<StructuredFormatDisplayAttribute("Tree {Contents}")>]
type Tree(node: int, elems: Tree list) =
member x.Contents = (node, elems)
let c = Tree (1, [ Tree (2, []); Tree (3, [ Tree (4, []) ]) ])
let c2 = Tree (1, [ c; c])
let c3 = Tree (1, [ c2; c2])
产生令人舒适的结果:
val c3 : Tree =
Tree (1,
[Tree (1,
[Tree (1, [Tree (2, []); Tree (3, [Tree (4, [])])]);
Tree (1, [Tree (2, []); Tree (3, [Tree (4, [])])])]);
Tree (1,
[Tree (1, [Tree (2, []); Tree (3, [Tree (4, [])])]);
Tree (1, [Tree (2, []); Tree (3, [Tree (4, [])])])])])
通常,你也应该考虑实现ToString方法,如果你还经常使用VS debugger,也应该考虑添加一个DebuggerDisplay属性.
原文链接: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
我想改变一些类型在fsi输出中的格式,尤其是集合类型。怎样的方法才是比较合理的呢?….有哪位朋友可以提供一点信息吗? 或者一些指南和示例那就更好了。
下面就是一些在F#Interactive中格式化数据的技巧。 这并不足以理解为一个指南,这仅仅能帮你入门。如果你需要更多的示例,请联系我。
对F# interactive来说,一个简单的方法就是使用fsi.AddPrintTransformer来生成一个显示对象的替代品(或者使用更小的、产生一个字符串的fsi.AddPrinter函数),例如:
type C(elems:int list) =
member x.Contents = elems
member x.IsBig = elems.Length > 100
let c = C [1;2;3]
fsi.AddPrintTransformer (fun (c:C)-> box c.Contents)
产生:
val c : C = [1; 2; 3]
AddprintTransformer有一点很好,你可以让它成为有条件的——返回null 来表明formatter(用来格式化的一串字符)应该被忽略:
fsi.AddPrintTransformer (fun (c:C)->
if c.IsBig then
null else box c.Contents)
有一点非常好,如果你将它和“obj”类型一起使用,你可以对任意的对象作特定的格式化:
fsi.AddPrintTransformer (fun (obj:obj)->
match obj with :? C
as c -> box c.Contents | _->
null)
这里有一个问题,fsi.AddPrinter和fsi.AddPrintTransformer不会更改位于sprintf、printf等函数中的%A的行为。对于那些设置一个简单标志(即命名一个成员属性产生一个代理对象)而受限制的类型,以及一些周围的文字:
[<StructuredFormatDisplayAttribute("CCC {Contents}")>]
type C(elems:int list) =
member x.Contents = elems
let c = C [1;2;3]
产生:
val c : C = CCC [1; 2; 3]
如果你的类型是一个普通的集合类, 那么使用一个list 或者sequence 作为这个替代对象。
如果你的类型是一个matirx或者table 类型,那么使用一个2D array作为这个替代对象。
如果你的类型在逻辑上说是一个union 类型,但你已经隐藏了其背后的抽象边界的表现形式,那么可以考虑使用一个独立的、能够解开你的对象的结构的helper union 类型(如:如果你的类型是一个递归类型,那么可以解开它的第一层)
如果你的数据是递归树型的,你可以描述它的子树为一个list:
[<StructuredFormatDisplayAttribute("Tree {Contents}")>]
type Tree(node: int, elems: Tree list) =
member x.Contents = (node, elems)
let c = Tree (1, [ Tree (2, []); Tree (3, [ Tree (4, []) ]) ])
let c2 = Tree (1, [ c; c])
let c3 = Tree (1, [ c2; c2])
产生令人舒适的结果:
val c3 : Tree =
Tree (1,
[Tree (1,
[Tree (1, [Tree (2, []); Tree (3, [Tree (4, [])])]);
Tree (1, [Tree (2, []); Tree (3, [Tree (4, [])])])]);
Tree (1,
[Tree (1, [Tree (2, []); Tree (3, [Tree (4, [])])]);
Tree (1, [Tree (2, []); Tree (3, [Tree (4, [])])])])])
通常,你也应该考虑实现ToString方法,如果你还经常使用VS debugger,也应该考虑添加一个DebuggerDisplay属性.
原文链接: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
相关文章推荐
- F# Interactive技巧:在sprintf/printf/fprintf中使用AddPrinter,addPrintTransformer和%A来格式化数据
- sprintf 与vsnprintf格式化数据的使用方式
- fprintf、printf、sprintf、fscanf、scanf、sscanf 格式化输入输出
- fprintf、printf、sprintf、fscanf、scanf、sscanf 格式化输入输出
- fprintf、printf、sprintf、fscanf、scanf、sscanf 格式化输入输出
- sprintf 编辑 sprintf指的是字符串格式化命令,主要功能是把格式化的数据写入某个字符串中。sprintf 是个变参函数。使用sprintf 对于写入buffer的字符数是没有
- usart下位机输出使用printf的格式化技巧
- C语言--格式化输入/输出函数(printf/scanf,fprintf/fscanf,sprintf,sscanf)
- fprintf、printf、sprintf、fscanf、scanf、sscanf 格式化输入输出【转】
- fprintf、printf、sprintf、fscanf、scanf、sscanf 格式化输入输出
- fprintf、printf、sprintf、fscanf、scanf、sscanf 格式化输入输出
- fprintf、printf、sprintf、fscanf、scanf、sscanf 格式化输入输出
- PHP字符串函数之 sscanf echo print sprintf vsprintf printf vprintf fprintf vfprintf
- PHP字符串函数之 sscanf echo print sprintf vsprintf printf vprintf fprintf vfprintf
- PHP格式化输出printf,sprintf,vprintf,fprintf
- delphi中使用SocketStream读写数据的技巧
- PHP中echo、print、print_r、printf、sprintf和var_dump的区别比较那些事!
- springMVC4(11)使用注解完成数据格式化
- C语言fprintf()函数:输出函数(格式化输出数据至文件)
- 使用格式化显示数据