@Leeの答えは可能な回避策として正しいですが、コードで何が起こるかについては説明していません。
式printf "foo"
で、"foo"
は書式設定する文字列ではありません。代わりに、それ自体が入力フォーマッタです。より具体的には、 の実際の型を推測するために使用される文字列リテラルTextWriterFormat<'T>
です。
の署名printf
は次のとおりです。
printf : TextWriterFormat<'T> -> 'T
printfn ("DANNY")
には書式指定子が含まれていないため、F# コンパイラは a を推論し、TextWriterFormat<unit>
式全体が になりprintfn ("DANNY") ()
ます。
変数を使用すると、どの書式指定子が存在するかを静的に予測することは不可能です。メソッドがまたはToLongTimeString()
の文字列を返すことができた場合、返される関数のプロトタイプは何でしょうか?"%s"
"%d %d %d"
正しい型を推測する場合、文字列リテラルは正常に機能しますが、変数またはlet
バインドは機能しません。
let foo1 = "foo"
let bar = printf foo // does not compile
[<Literal>] let foo2 = "foo";; // see update below
let bar = printf foo2 // compiles fine
いずれにせよ、常にフォーマット指定子を使用する方がはるかに安全に見えます:
printf "%s" "DANNY"
printf "%s" (DateTime.Now.ToLongTimeString())
更新: VS2013 で警告 FS0058を回避するために、値の;;
後に二重コロンを入力することを忘れないでください。[<Literal>]