将OCaml字符串转换为format6

将OCaml字符串转换为format6,ocaml,Ocaml,以下代码未编译: let x = "hello" in Printf.printf x 错误是: Error: This expression has type string but an expression was expected of type ('a, out_channel, unit) format = ('a, out_channel, unit, unit, unit, unit) format6 1) 有人能解释一下错误信息吗 2) 为什么不能将字

以下代码未编译:

let x = "hello" in
Printf.printf x
错误是:

Error: This expression has type string but an expression was expected of type
     ('a, out_channel, unit) format =
       ('a, out_channel, unit, unit, unit, unit) format6
1) 有人能解释一下错误信息吗


2) 为什么不能将字符串传递给printf?

正如sepp2k所指出的,在OCaml
printf中,格式具有独特的类型,而不仅仅是字符串。字符串文字会自动转换为
printf
格式,但
x
不是字符串文字。如果要为格式命名,可以自己显式转换:

> let x = format_of_string "hello" in Printf.printf x
hello- : unit = ()
您也可以通过为x指定类型来实现隐式转换,但是格式的类型非常复杂,这非常痛苦:

# let (x: ('a,'b,'c,'d,'d,'a) format6) = "hello" in Printf.printf x;;
hello- : unit = ()

(我个人不理解
格式6
类型。)

printf的第一个参数必须是
类型('a,out\u channel,unit)格式,而不是字符串。字符串文本可以自动转换为适当的格式类型,但字符串通常不能

原因是格式字符串的确切类型取决于字符串的内容。例如,表达式
printf“%d-%d”
的类型应该是
int->int->()
,而
printf“%s”
的类型应该是
string->()
。显然,当编译时不知道格式字符串时,这种类型检查是不可能的


在您的情况下,只需执行
printf“%s”x

注意,like
printf
format\u of_string
只能与字符串文字一起使用,而不能与任意字符串一起使用。因此,如果需要将
x
作为字符串,则不能在打印前使用它将
x
转换为格式。正如您所指出的,在编译时需要知道字符串以获得类型安全性。我想这是强静态类型语言的双刃剑:)或者您可以只执行
print\u string x
。即使在C中,将一些变量字符串作为格式传递给printf@newacct:事实并非如此,想想dbg(const char*fmt,…)函数,您可以声明自己。@Nicolasvien在OCaml中无法正常工作:
让dbg fmt=Printf.Printf fmt在dbg“%d%d”1 2
中。您唯一不能做的事情是使用从文件读取的格式字符串或作为用户输入。另请参见此问题: