根据可能的解决方法,@Lee 的答案是正确的,但它没有描述您的代码会发生什么。
在表达式printf "foo"
中,"foo"
不是要格式化的字符串。相反,它本身就是输入格式化程序。更具体地说,它是一个字符串文字,用于推断TextWriterFormat<'T>
.
的签名printf
是:
printf : TextWriterFormat<'T> -> 'T
由于printfn ("DANNY")
不包含任何格式说明符,F# 编译器推断 a TextWriterFormat<unit>
,整个表达式变为printfn ("DANNY") ()
.
使用变量,不可能静态地预测将出现什么格式说明符。考虑如果ToLongTimeString()
方法能够返回"%s"
or的字符串"%d %d %d"
,返回函数的原型是什么?
推断正确类型时,字符串文字可以正常工作,但变量或let
-binding 不起作用:
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())
更新:不要忘记在值;;
后输入双冒号[<Literal>]
以避免在 VS2013 中出现警告FS0058。