Chaînes interpolées

Les chaînes interpolées sont des chaînes qui vous permettent d’incorporer des expressions F# dans celles-ci. Ils sont utiles dans un large éventail de scénarios où la valeur d’une chaîne peut changer en fonction du résultat d’une valeur ou d’une expression.

Syntaxe

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

Remarques

Les chaînes interpolées vous permettent d’écrire du code dans des « trous » à l’intérieur d’un littéral de chaîne. Voici un exemple de base :

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

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

Le contenu entre chaque {} paire d’accolades peut être n’importe quelle expression F#.

Pour l’interpolation à valeur de chaîne en F# 11, une expression non mise en forme utilise la conversion de string F#. Si l’expression prend la valeur null, une chaîne vide est utilisée. Les compilateurs antérieurs pouvaient optimiser certaines interpolations de chaîne uniquement, mais elles utilisaient sinon la mise en forme printf ; consultez l’interpolation native AOT et chaîne pour connaître les différences de mise en forme.

Pour les chaînes interpolées typées avec des spécificateurs de format (par exemple %s{expr}%d{expr}), la conversion suit les règles définies pour ce spécificateur de format spécifique. Pour échapper à une paire d’accolades {} , écrivez deux d’entre eux comme suit :

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

Chaînes interpolées typées

Les chaînes interpolées peuvent également avoir des spécificateurs de format F# pour appliquer la sécurité des types.

let name = "Phillip"
let age = 30

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

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

Dans l’exemple précédent, le code passe par erreur la age valeur où name doit être, et vice/versa. Étant donné que les chaînes interpolées utilisent des spécificateurs de format, il s’agit d’une erreur de compilation au lieu d’un bogue d’exécution subtil.

Chaînes interpolées verbatim

F# prend en charge les chaînes interpolées détaillées de deux façons :

Utilisation $@ ou @$ préfixe

Vous pouvez combiner le préfixe $ d’interpolation avec le préfixe @ de chaîne détaillé dans n’importe quel ordre. Les chaînes détaillées ignorent les séquences d’échappement (à l’exception de "" représenter un guillemet) et peuvent s’étendre sur plusieurs lignes. Cela est particulièrement utile lors de l’utilisation de chemins d’accès ou de chaînes de fichiers contenant des barres obliques inverses et des guillemets.

let name = "Alice"
let path = @"C:\Users\Alice\Documents"

// Using $@ prefix
printfn $@"User {name} has files in: {path}"

// Using @$ prefix (also valid)
printfn @$"User {name} has files in: {path}"

// Embedding quotes - use "" to represent a single "
let message = $@"He said ""{name}"" is here"

Utilisation de guillemets triples

F# prend également en charge les chaînes interpolées détaillées avec des guillemets triples afin que vous puissiez incorporer des littéraux de chaîne sans échapper.

let age = 30

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

Spécificateurs de format

Les spécificateurs de format peuvent être printf-style ou . Style NET. Les spécificateurs de style Printf sont ceux couverts dans la mise en forme en texte clair, placés avant les accolades. Par exemple:

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

Le spécificateur %A de format est particulièrement utile pour produire la sortie de diagnostic des données F# structurées.

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

. Les spécificateurs de style NET sont utilisables avec String.Format, placés après une : accolade. Par exemple:

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

Si un . Le spécificateur de style NET contient un caractère inhabituel, puis il peut être échappé à l’aide de double backticks :

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

Alignement d’expressions dans des chaînes interpolées

Vous pouvez aligner ou aligner à gauche des expressions à l’intérieur de chaînes | interpolées et une spécification du nombre d’espaces. La chaîne interpolée suivante aligne les expressions de gauche et de droite à gauche et à droite, respectivement, par sept espaces.

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

Chaînes interpolées et FormattableString mise en forme

Vous pouvez également appliquer la mise en forme qui respecte les règles pour 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."

En outre, une chaîne interpolée peut également être vérifiée en tant que FormattableString par le biais d’une annotation de type :

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

Notez que l’annotation de type doit se trouver sur l’expression de chaîne interpolée elle-même. F# ne convertit pas implicitement une chaîne interpolée en un FormattableString.

Syntaxe étendue pour l’interpolation de chaîne

À compter de F# 8, lorsque vous travaillez avec du texte contenant plusieurs caractères ou {} plusieurs %caractères, vous pouvez utiliser la syntaxe d’interpolation de chaîne étendue pour supprimer la nécessité d’échapper.

Les littéraux de chaîne de guillemets triples peuvent commencer par plusieurs $ caractères, ce qui modifie le nombre d’accolades requises pour ouvrir et fermer l’interpolation. Dans ces littéraux de chaîne, { et } les caractères n’ont pas besoin d’être échappés :

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."""

Le nombre de caractères nécessaires pour les spécificateurs de % format est affecté de la même façon :

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

Interpolation native AOT et valeur de chaîne

Pour mettre en forme du texte sans moteur de mise en forme basé sur la réflexion, utilisez l’interpolation à valeur chaîne avec des trous de format brut ou .NET :

let name = "Ada"
let score = 97.5
let message: string = $"{name}: {score:F1}"
printn message
// Ada: 97.5

F# 11 utilise des conversions directes et System.String.Concat pour d’autres interpolations à valeur chaîne. Un trou au format .NET utilise invariant String.Format et les cases de son argument. Ces modifications du compilateur prennent en charge L’AOT natif sans nécessiter la build core moderne ; d’autres codes d’application peuvent toujours avoir besoin de réflexion.

Les trous de style Printf nécessitant une mise en forme printf, comme %04d{number} ou %A{record}, peuvent toujours utiliser le chemin basé sur la réflexion. Bare %s, , %c, %d, , %iet %M trous conservent leurs vérifications de type et évitent la mise en forme printf. D’autres spécificateurs, y compris %u, ne sont pas couverts par cette optimisation. Une interpolation utilisée comme PrintfFormat valeur est également distincte de celle dont le type de résultat est string.

Compatibilité de la culture et du format

Les trous simples utilisent la conversion de string F# ; .NET-format trous utilisent une mise en forme invariante. Pour produire une sortie localisée, sélectionnez explicitement la culture :

open System.Globalization

let value = 12.5m
let machineText: string = $"{value:F2}"
let displayText =
    value.ToString("F2", CultureInfo.GetCultureInfo("fr-FR"))

assert (machineText = "12.50")
assert (displayText = "12,50")

Vérifiez la sortie localisée lors de la mise à niveau. FormattableString conserve ses arguments pour la mise en forme ultérieure basée sur un fournisseur au lieu de suivre ce chemin de concaténation.

Avertissement FS3884 identifie une fonction non approuvée ou un délégué dans un trou d’interpolation. Appliquez la fonction si vous avez prévu son résultat :

let weight () = 12.5m
let text: string = $"Weight: {weight ()} kg"

Écrire une valeur dans une sortie standard

Pour écrire une valeur sans format printf, FSharp.Core 11 ajoute print et printn. Ils utilisent string la conversion ; printn ajoute une nouvelle ligne :

print "Parcels: "
printn 3

Pour la sortie structurelle %A , utilisez la mise en forme en texte clair.

Enregistrer et unionr la sortie sans réflexion

Avec --reflectionfree, F# 11 peut générer des implémentations significatives ToString pour les enregistrements et les unions au lieu d’afficher uniquement le nom du type :

type Reading = { Sensor: string; Value: int }
type Outcome = Recorded of Reading | Unavailable

let reading = { Sensor = "north"; Value = 12 }
printn reading
printn (Recorded reading)

L’exemple de projet active l’indicateur. La sortie diffère de ; les types de %Achamps nécessitent également des implémentations appropriées ToString .

Voir aussi