谁能解释为什么这会导致错误:
let xs = [| "Mary"; "Mungo"; "Midge" |]
Array.iter printfn xs
虽然这不会:
Array.iter printfn [| "Mary"; "Mungo"; "Midge" |]
谁能解释为什么这会导致错误:
let xs = [| "Mary"; "Mungo"; "Midge" |]
Array.iter printfn xs
虽然这不会:
Array.iter printfn [| "Mary"; "Mungo"; "Midge" |]
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
除了@pad 的出色回答。
造成混淆的主要原因是误解了论点会发生什么。让我们看一下单次迭代。它应该是
printfn "%s" "Mary" // or whatever default format specifier instead of %s
但事实上,它是
printfn "Mary" ()
所以"Mary"
不是要格式化的字符串。它是一个格式说明符,非常无用,但非常适合格式化unit
.
尝试对您的示例进行此修改:
Array.iter printfn [| "Mary %s"; "Mungo"; "Midge" |]
它会拒绝编译。