简体   繁体   English

F#printfn异常

[英]F# printfn anomaly

Can anyone please explain why this results in an error: 谁能解释这导致错误的原因:

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

Array.iter printfn xs

Whilst this does not: 虽然这不能:

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

The signature of printfn is Printf.TextWriterFormat<'a> -> 'a . printfn的签名是Printf.TextWriterFormat<'a> -> 'a The compiler infers literal values of strings as Printf.TextWriterFormat<unit> but cannot do so with dynamic strings. 编译器将字符串的文字值推断为Printf.TextWriterFormat<unit>但不能对动态字符串进行推断。

You can help the compiler in the first example by adding correct type annotation: 您可以通过添加正确的类型注释来帮助第一个示例中的编译器:

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

or using explicit constructors: 或使用显式构造函数:

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

In general, it's too verbose to do so. 通常,这样做太冗长。 Therefore, specifying format strings such as "%s" for strings and "%O" for types overriding ToString() method is the good way to go: 因此,为字符串指定格式字符串,例如"%s" ,为类型指定"%O"以覆盖ToString()方法是一个好方法:

let xs = [| "Mary"; "Mungo"; "Midge" |]
Array.iter (printfn "%s") xs

In addition to @pad's excellent answer. 除了@pad的出色答案。

The main reason for confusion is misunderstanding of what happens with the arguments. 造成混淆的主要原因是对论据发生了误解。 Let's look at single iteration. 让我们看一下单迭代。 It supposed to be 应该是

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

but in fact, it is 但是实际上

printfn "Mary" ()

So "Mary" is not a string to be formatted. 因此, "Mary"不是要格式化的字符串。 It is a format specifier , quite useless but well suitable for formatting a unit . 它是一种格式说明符 ,虽然没什么用,但非常适合格式化一个unit

Try this modification to your sample: 尝试对您的示例进行此修改:

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

and it will refuse to compile. 它将拒绝编译。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM