内插字符串

内插字符串允许向其本身嵌入 F# 表达式。 在字符串的值可能基于值或表达式的结果而更改的多种情况中,此字符串都非常有用。

语法

$"string-text {expr}"
$"string-text %format-specifier{expr}"
$"""string-text {"embedded string literal"}"""
$$"""string-text %%format-specifier{{expr}}"""

备注

通过使用内插字符串,可在字符串字面量的“孔”中编写代码。 下面是一个基本示例:

let name = "Phillip"
let age = 30
printfn $"Name: {name}, Age: {age}"

printfn $"I think {3.0 + 0.14} is close to {System.Math.PI}!"

每个 {} 大括号对之间的内容可以是任何 F# 表达式。

若要转义 {} 大括号对,请编写两个大括号对,如下所示:

let str = $"A pair of braces: {{}}"
// "A pair of braces: {}"

类型化内插字符串

内插字符串还可以使用 F# 格式说明符来强制实现类型安全性。

let name = "Phillip"
let age = 30

printfn $"Name: %s{name}, Age: %d{age}"

// Error: type mismatch
printfn $"Name: %s{age}, Age: %d{name}"

在上一示例中,代码错误地传递了 age 值和 name 值的相互位置。 由于内插字符串使用格式说明符,因此这是编译错误,而不是细微的运行时 bug。

逐字内插字符串

F# 支持带三引号的逐字内插字符串,以便可以嵌入字符串文本。

let age = 30

printfn $"""Name: {"Phillip"}, Age: %d{age}"""

格式说明符

格式说明符可以是 printf 样式或 .NET 样式。 printf 样式的说明符采用纯文本格式设置,放置在大括号之前。 例如:

let pi = $"%0.3f{System.Math.PI}"  // "3.142"
let code = $"0x%08x{43962}"  // "0x0000abba"

格式说明符 %A 对于生成结构化 F# 数据的诊断输出特别有用。

let data = [0..4]
let output = $"The data is %A{data}"  // "The data is [0; 1; 2; 3; 4]"

.NET 样式的说明符可用于 String.Format,放置在大括号内的 : 之后。 例如:

let pi = $"{System.Math.PI:N4}"  // "3.1416"
let now = $"{System.DateTime.UtcNow:``yyyyMMdd``}" // e.g. "20220210"

如果 .NET 样式说明符包含异常字符,可以使用双反引号对其进行转义:

let nowDashes = $"{System.DateTime.UtcNow:``yyyy-MM-dd``}" // e.g. "2022-02-10"

对齐内插字符串中的表达式

可以通过使用 | 并指定空格数来在内插字符串内将表达式进行左对齐或右对齐。 以下内插字符串按 7 个空格的间距将左侧和右侧的表达式分别向左侧和右侧对齐。

printfn $"""|{"Left",-7}|{"Right",7}|"""
// |Left   |  Right|

内插字符串和 FormattableString 格式设置

还可以应用符合 FormattableString 规则的格式设置:

let speedOfLight = 299792.458
printfn $"The speed of light is {speedOfLight:N3} km/s."
// "The speed of light is 299,792.458 km/s."

此外,还可通过类型注释将内插字符串类型检查为 FormattableString

let frmtStr = $"The speed of light is {speedOfLight:N3} km/s." : FormattableString
// Type: FormattableString
// The speed of light is 299,792.458 km/s.

请注意,类型注释必须位于内插字符串表达式本身上。 F# 不会将内插字符串隐式转换为 FormattableString

字符串内插的扩展语法

从 F# 8 开始,在处理已包含多个 {}% 字符的文本时,可以使用扩展字符串内插语法来消除转义需求。

三引号字符串字面量可以多个 $ 字符开头,这会更改打开和关闭内插所需的大括号数。 在这些字符串字面量中,不需要转义 {} 字符:

let str = $$"""A string containing some {curly braces} and an {{"F#" + " " + "expression"}}."""
// "A string containing some {curly braces} and an F# expression."
let another = $$$"""A string with pairs of {{ and }} characters and {{{ "an F# expression" }}}."""
// "A string with pairs of {{ and }} characters and an F# expression."""

格式说明符所需的 % 字符数受到同样的影响:

let percent = $$"""50% of 20 is %%.1f{{20m * 0.5m}}"""
// "50% of 20 is 10.0"

请参阅