第七章 F# 库(四)
打印(Microsoft.FSharp.Text.Printf)模块
打印(Printf)模块提供了以类型案例的方式格式化字符串的函数,打印模块中函数的第一个参数是值的占位符,它返回的函数需要为占位符提供值;占位符用百分号加一个表示类型的字母组成,表 7-2 是完整的清单。
表 7-2 打印模块的占位符和标记
标记 | 描述 |
%b | 布尔型,格式化为 “true” 或 “false” |
%s | 字符串,格式化为它的非转义内容 |
%d, %i | 任何基本整型(即,sbyte, byte, int16, uint16, int32, uint32, int64, uint64, nativeint, or unativeint),格式化为十进制整数,符号依基本整型 |
%u | 任何基本整型,格式化为无符号的十进制整数 |
%x, %X, %o | 任何基本整型,格式化为无符号的十六进制数(a-f),十六进制数(A-F),八进制数 |
%e, %E | 任何基本浮点数(即,float 或 float32),使用 C 风格的浮点格式规范进行格式化,有符号值的组成:[-]d.dddde[sign]ddd,其中:d 是一个十进制数字,dddd 是一个或多个十进制数字,ddd是三个十进制数字,sign 是 + 或 - |
%f | 任何基本浮点数,使用 C 风格的浮点格式规范进行格式化,有符号值的组成:[-]dddd.dddd,其中:dddd 是一个或多个十进制数字;小数点前面数字的多少取决于值的大小,后面数字的多少取决于要求的精度 |
%g, %G | 任何基本浮点数,使用 C 风格的浮点格式规范进行格式化,有符号值以 f 或 e 格式打印,对于给定的值和精度,看哪一个更紧凑 |
%M | System.Decimal 值 |
%O | 任意值,打印装箱(boxing)的对象,使用它的 ToString 方法 |
%A | 任意值,打印出的值很智能,用户可以看到属性和字段的值 |
%a | 一个是函数,它也有两个参数,其一是上下文参数,与给定的格式化函数(比如 System.IO.TextWriter)相对应的类型,其二是打印的值,可以输出或返回适当的文本;另一个是实际要打印的值 |
%t | 通用格式分类符,要求一个是函数的参数:它也有两个参数,其一是上下文参数,与给定的格式化函数(比如 System.IO.TextWriter)相对应的类型,其二是打印的值,可以输出或返回适当的文本 |
0 | 这个标记表示用加 0 代替空格组成要求的宽度 |
- | 这个标记表示在指定的宽度内左对齐 |
+ | 这个标记表示,如果为正数,加上 + 号(负数对应 - 号) |
' ' | 如果为负数额外加上空格(负数对应 - 号) |
下面的示例演示如何使用 printf 函数,创建一个函数,需要一个字符串,然后,把字符串传递给这个函数。
Printf.printf "Hello %s""Robert"
代码的运行结果如下:
Hello Robert
这个示例的意义可能并不十分明显,下面的示例有助于解释原因。如果传递给printf 函数的类型错误,就不能编译通过:
Printf.printf "Hello %s" 1
前面的代码不能编译通过,出现下面的错误:
Prog.fs(4,25): error: FS0001: Thisexpression has type
int
but is here used with type
string
这对类型推断(type inference)也有影响。如果创建的函数使用 printf,那么,传递给 printf 的任意参数都会从这里推断出类型。例如,下面代码中函数myPrintInt 的类型为int -> unit,是因为其中包含了 printf 函数:
let myPrintInt x =
Printf.printf"An integer: %i" x
打印模块中函数的基本占位符,布尔型是 %b,字符串是 %s,整型为 %d 或 %i,无符号整型为 %u,而%x、%X 或 %o 则格式化为十六进制和八进制数[ 原文有误];在数值型显示中指定小数倍数也是可能的,下面的示例有演示:
let pi = System.Math.PI
Printf.printfn "%f" pi
Printf.printfn "%1.1f" pi
Printf.printfn "%2.2f" pi
Printf.printfn "%2.8f" pi
代码的运行结果如下:
3.141593
3.1
3.14
3.14159265
打印模块中还有大量其他函数,格式化字符串的方法同 printf 本身,但是,结果可以写到不同的地方。下面的示例演示了一些不同的版本:
// write to a string
let s = Printf.sprintf "Hello%s\r\n" "string"
printfn "%s" s
// prints the string to a .NET TextWriter
Printf.fprintf System.Console.Out"Hello %s\r\n" "TextWriter"
// create a string that will be placed
// in an exception message
Printf.failwithf "Hello %s""exception"
代码的运行结果如下:
Hello string
Hello channel [ 有误,好像没有这一句 ]
Hello TextWriter
Microsoft.FSharp.FailureException: Helloexception
atMicrosoft.FSharp.Text.Printf.failwithf@60.Invoke(String s)
atMicrosoft.FSharp.Text.PrintfImpl.Make@188.Invoke(A inp))
at<StartupCode>.FSI_0003._main()
stopped due to error