3

谁能解释为什么这会导致错误:

let xs = [| "Mary"; "Mungo"; "Midge" |]

Array.iter printfn xs

虽然这不会:

Array.iter printfn [| "Mary"; "Mungo"; "Midge" |]
4

2 回答 2

7

printfn 的签名是Printf.TextWriterFormat<'a> -> 'a. 编译器将字符串的文字值推断为Printf.TextWriterFormat<unit>动态字符串,但不能这样做。

您可以通过添加正确的类型注释来帮助第一个示例中的编译器:

let xs: Printf.TextWriterFormat<unit> [] = [| "Mary"; "Mungo"; "Midge" |]
Array.iter printfn xs

或使用显式构造函数:

let xs = [| "Mary"; "Mungo"; "Midge" |]
Array.iter (fun s -> printfn <| Printf.TextWriterFormat<unit>(s)) xs

一般来说,这样做太冗长了。因此,指定格式字符串(例如"%s"for strings 和"%O"for types 覆盖ToString()方法)是一个不错的方法:

let xs = [| "Mary"; "Mungo"; "Midge" |]
Array.iter (printfn "%s") xs
于 2012-07-29T10:15:56.323 回答
3

除了@pad 的出色回答。

造成混淆的主要原因是误解了论点会发生什么。让我们看一下单次迭代。它应该是

printfn "%s" "Mary" // or whatever default format specifier instead of %s

但事实上,它是

printfn "Mary" ()

所以"Mary"不是要格式化的字符串。它是一个格式说明符,非常无用,但非常适合格式化unit.

尝试对您的示例进行此修改:

Array.iter printfn [| "Mary %s"; "Mungo"; "Midge" |]

它会拒绝编译。

于 2012-07-29T16:32:06.973 回答