Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Las cadenas interpoladas son cadenas que permiten insertar expresiones de F# en ellas. Son útiles en una amplia gama de escenarios en los que el valor de una cadena puede cambiar en función del resultado de un valor o expresión.
Sintaxis
$"string-text {expr}"
$"string-text %format-specifier{expr}"
$@"string-text {expr}"
@$"string-text {expr}"
$"""string-text {"embedded string literal"}"""
$$"""string-text %%format-specifier{{expr}}"""
Observaciones
Las cadenas interpoladas permiten escribir código en "agujeros" dentro de un literal de cadena. Este es un ejemplo básico:
let name = "Phillip"
let age = 30
printfn $"Name: {name}, Age: {age}"
printfn $"I think {3.0 + 0.14} is close to {System.Math.PI}!"
El contenido entre cada {} par de llaves puede ser cualquier expresión de F#.
Para la interpolación con valores de cadena en F# 11, una expresión sin formato usa la conversión de string F#. Si la expresión se evalúa como null, se usa una cadena vacía. Los compiladores anteriores podrían optimizar algunas interpolaciones de solo cadena, pero, de lo contrario, usaron formato printf; consulte Interpolación de valores de cadena y AOT nativo para conocer las diferencias de formato.
Para las cadenas interpoladas con tipo con especificadores de formato (como %s{expr} o %d{expr}), la conversión sigue las reglas definidas para ese especificador de formato específico.
Para escapar de un {} par de llaves, escriba dos de ellos de la siguiente manera:
let str = $"A pair of braces: {{}}"
// "A pair of braces: {}"
Cadenas interpoladas tipadas
Las cadenas interpoladas también pueden tener especificadores de formato F# para aplicar la seguridad de tipos.
let name = "Phillip"
let age = 30
printfn $"Name: %s{name}, Age: %d{age}"
// Error: type mismatch
printfn $"Name: %s{age}, Age: %d{name}"
En el ejemplo anterior, el código pasa erróneamente el age valor donde name debe ser y viceversa. Dado que las cadenas interpoladas usan especificadores de formato, se trata de un error de compilación en lugar de un error sutil en tiempo de ejecución.
Cadenas interpoladas textuales
F# admite cadenas interpoladas textualmente de dos maneras:
Uso $@ o @$ prefijo
Puede combinar el prefijo de interpolación con el prefijo $@ de cadena textual en cualquier orden. Las cadenas textuales omiten las secuencias de escape (excepto para "" representar una comilla) y pueden abarcar varias líneas. Esto resulta especialmente útil cuando se trabaja con rutas de acceso de archivo o cadenas que contienen barras diagonales inversas y comillas.
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"
Uso de comillas triples
F# también admite cadenas interpoladas textuales con comillas triples para poder insertar literales de cadena sin escape.
let age = 30
printfn $"""Name: {"Phillip"}, Age: %d{age}"""
Especificadores de formato
Los especificadores de formato pueden ser de estilo printf o . Estilo NET. Los especificadores de estilo printf son los que se tratan en formato de texto no cifrado, colocados antes de las llaves. Por ejemplo:
let pi = $"%0.3f{System.Math.PI}" // "3.142"
let code = $"0x%08x{43962}" // "0x0000abba"
El especificador %A de formato es especialmente útil para generar la salida de diagnóstico de datos estructurados de F#.
let data = [0..4]
let output = $"The data is %A{data}" // "The data is [0; 1; 2; 3; 4]"
. Los especificadores de estilo NET son los que se pueden usar con String.Format, colocados después de las : llaves. Por ejemplo:
let pi = $"{System.Math.PI:N4}" // "3.1416"
let now = $"{System.DateTime.UtcNow:``yyyyMMdd``}" // for example, "20220210"
Si es . El especificador de estilo NET contiene un carácter inusual y, a continuación, se puede escapar mediante caracteres de doble retroceso:
let nowDashes = $"{System.DateTime.UtcNow:``yyyy-MM-dd``}" // for example, "2022-02-10"
Alineación de expresiones en cadenas interpoladas
Puede alinear a la izquierda o alinear las expresiones a la derecha dentro de cadenas interpoladas con | y una especificación de cuántos espacios. La siguiente cadena interpolada alinea las expresiones izquierda y derecha a la izquierda y derecha, respectivamente, por siete espacios.
printfn $"""|{"Left",-7}|{"Right",7}|"""
// |Left | Right|
Cadenas interpoladas y FormattableString formato
También puede aplicar formato que cumpla las reglas de 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."
Además, una cadena interpolada también se puede comprobar como una FormattableString mediante una anotación de tipo:
let frmtStr = $"The speed of light is {speedOfLight:N3} km/s." : FormattableString
// Type: FormattableString
// The speed of light is 299,792.458 km/s.
Tenga en cuenta que la anotación de tipo debe estar en la propia expresión de cadena interpolada. F# no convierte implícitamente una cadena interpolada en .FormattableString
Sintaxis extendida para la interpolación de cadenas
A partir de F# 8, cuando se trabaja con texto que contiene varios {} caracteres o % ya, puede usar la sintaxis de interpolación de cadenas extendida para quitar la necesidad de escapar.
Los literales de cadena de comillas triples pueden comenzar con varios $ caracteres, lo que cambia cuántas llaves son necesarias para abrir y cerrar la interpolación.
En estos literales de cadena y {} no es necesario que se escapen los caracteres:
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."""
El número de % caracteres necesarios para los especificadores de formato se ve afectado de la misma manera:
let percent = $$"""50% of 20 is %%.1f{{20m * 0.5m}}"""
// "50% of 20 is 10.0"
Interpolación nativa con valores de cadena y AOT
Para dar formato al texto sin un motor de formato basado en reflexión, use la interpolación con valores de cadena con agujeros de formato sin formato o .NET:
let name = "Ada"
let score = 97.5
let message: string = $"{name}: {score:F1}"
printn message
// Ada: 97.5
F# 11 usa conversiones directas y System.String.Concat para más interpolaciones con valores de cadena. Un agujero de formato .NET usa lavariante String.Format y los cuadros de su argumento. Estos cambios del compilador admiten AOT nativo sin necesidad de la compilación core moderna; Otro código de aplicación todavía puede necesitar reflexión.
Los agujeros de estilo printf que requieren formato printf, como %04d{number} o %A{record}, todavía pueden usar la ruta de acceso basada en reflexión. Los agujeros , %c, %d, %iy %M desnudos %sconservan sus comprobaciones de tipos y evitan el formato printf. Otros especificadores, incluidos , no están cubiertos %upor esa optimización. Una interpolación utilizada como valor PrintfFormat también es distinta de una cuyo tipo de resultado es string.
Compatibilidad con la referencia cultural y el formato
Los agujeros sin formato usan la conversión de string F#; .NET agujeros de formato usan formato invariable. Para generar una salida localizada, seleccione la referencia cultural explícitamente:
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")
Compruebe la salida localizada al actualizar.
FormattableString conserva sus argumentos para el formato basado en el proveedor posterior en lugar de seguir esta ruta de acceso de concatenación.
Advertencia FS3884 identifica una función o un delegado no aprobados en un agujero de interpolación. Aplique la función si pretende su resultado:
let weight () = 12.5m
let text: string = $"Weight: {weight ()} kg"
Escritura de un valor en la salida estándar
Para escribir un valor sin un formato printf, FSharp.Core 11 agrega print y printn. Usan string la conversión; printn agrega una nueva línea:
print "Parcels: "
printn 3
Para la salida estructural %A , use formato de texto no cifrado.
Salida de registro y unión sin reflexión
Con --reflectionfree, F# 11 puede generar implementaciones significativas ToString para registros y uniones en lugar de mostrar solo el nombre de tipo:
type Reading = { Sensor: string; Value: int }
type Outcome = Recorded of Reading | Unavailable
let reading = { Sensor = "north"; Value = 12 }
printn reading
printn (Recorded reading)
El proyecto de ejemplo habilita la marca . La salida difiere de %A; los tipos de campo también necesitan implementaciones adecuadas ToString .