这个问题发生的范围比操作员要广泛得多^
。基本上,OCaml 编译器需要知道您的格式字符串是文字字符串,并且需要在编译时知道文字字符串。否则,OCaml 无法在编译时将您的字符串转换为这种BLAHBLAH format6
类型。该Printf
模块仅适用于在编译时完全已知的格式字符串,或已转换为该BLAHBLAH format
类型的格式字符串。
通常,您可以通过使用运算符并在代码中使用这些字符串之前^^
将所有文字字符串显式转换为BLAHBLAH format
类型来解决此问题。
这是另一个例子:
# Printf.sprintf (if true then "%d" else "%d ") 2;;
Error: This expression has type string but an expression was expected of type
('a -> 'b, unit, string) format =
('a -> 'b, unit, string, string, string, string) format6
(* define a type abbreviation for brevity *)
# type ('a,'b) fformat = ('a ->'b, unit, string) format;;
type ('a, 'b) fformat = ('a -> 'b, unit, string) format
# Printf.sprintf (if true then ("%d":('a,'b)fformat) else ("%d ":('a,'b)fformat)) 2;;
- : string = "2"
OCaml 系统无法识别if ... then "a" else "b"
可以转换为BLAHBLAH format
. 如果您自己将每个文字字符串BLAHBLAH format
转换为,那么一切正常。if/then/else
(注意:如果您尝试将整个转换为,则它不起作用BLAHBLAH format
,因为 OCaml 无法验证您的字符串是否为文字。)
问题的根源是类型安全的要求:OCaml 要求每个等都有一个正确类型的参数%d
,并在编译时%s
保证这一点。除非在编译时知道整个格式字符串,否则不能保证类型安全。因此,不可能使用通过复杂算法计算的格式字符串,例如通过随机选择和。Printf
Printf
%s
%d
当我们if/then/else
用来计算格式字符串时,然后是 OCaml 的东西,哎呀,这是一个复杂的算法,在编译时验证类型安全是没有希望的。^^
运算符了解类型并在BLAHBLAH format
连接格式字符串时产生正确的结果。但是if/then/else
不知道BLAHBLAH format
,并且没有内置的替代方法if/then/else
(但我想你可以自己定义这样的东西)。