我从.net样式({0} ...)切换到printf样式的格式,并注意到特殊字符的格式不再被保留。
使用printf保留格式的技术是什么?
我正在做Printf.kprintf Log.Debug format
之类的事情。
我理解StringFormat会生成文字字符串(prenends为@“”)但printf不会。
编辑: 我基本上想要保留格式,比如反斜杠。如果我打印出一个文件路径,我希望看到“C:\ Program Files ...”不受干扰,就像StringFormat会打印一样。
答案 0 :(得分:3)
F#中有两种类型的字符串文字:普通字符串文字,看起来像"string"
和逐字字符串文字,看起来像@"string"
。无论哪种方式,字符串都会成为内存中.NET System.String
类型的实例,它们本质上只是char
值的序列。如果要创建包含某些字符(如反斜杠)的字符串,则在使用普通字符串文字时应该转义它们:"C:\\Program Files\\..."
,但在使用逐字字符串文字时不需要这样做:{{1 }}。无论哪种方式,内存中的值将由字符'C',':','\','P','r'等组成。您可能会发现忘记逃避反斜杠并不总是会导致问题,因为反斜杠只会在特定字符前面被解释为转义序列(所以你可以使用@"C:\Program Files\..."
而不是"C:\Program Files"
)。
一旦值在内存中,"C:\test"
和String.Format
系列函数的工作方式基本相同:
printf
你会发现所有这些值都是相同的(并且在正确的位置包含反斜杠)。同样地:
let sf1 = System.String.Format("{0}", "C:\\test")
let sf2 = System.String.Format("{0}", @"C:\test")
let pf1 = sprintf "%s" "C:\\test"
let pf2 = sprintf "%s" @"C:\test"
这些都是相同的,两者都被破坏了。
请注意let sf_bad = System.String.Format("{0}", "C:\test")
let pf_bad = sprintf "%s" "C:\test"
不会撤消创建字符串文字时发生的错位 - 它无法知道用户实际上并不想在字符串中嵌入制表符。
答案 1 :(得分:2)
如果您使用printfn
格式,%s
系列函数会打印字符串而不会进行任何转义
(%s
格式指定参数是字符串,应按原样打印):
> printfn "%s" "C:\\Test";;
C:\Test
val it : unit = ()
如果您使用%A
(它指定参数是任何对象并且应使用F#语法打印 - 请注意,这适用于列表),行为会有所不同。虽然这甚至没有逃脱"
字符:
> printfn "%A" "C:\\Test";;
"C:\Test"
val it : unit = ()