Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ciągi interpolowane to ciągi , które umożliwiają osadzanie w nich wyrażeń języka F#. Są one przydatne w wielu scenariuszach, w których wartość ciągu może ulec zmianie na podstawie wyniku wartości lub wyrażenia.
Składnia
$"string-text {expr}"
$"string-text %format-specifier{expr}"
$@"string-text {expr}"
@$"string-text {expr}"
$"""string-text {"embedded string literal"}"""
$$"""string-text %%format-specifier{{expr}}"""
Uwagi
Ciągi interpolowane umożliwiają pisanie kodu w "otworach" wewnątrz literału ciągu. Oto podstawowy przykład:
let name = "Phillip"
let age = 30
printfn $"Name: {name}, Age: {age}"
printfn $"I think {3.0 + 0.14} is close to {System.Math.PI}!"
Zawartość między każdą {} parą nawiasów klamrowych może być dowolnym wyrażeniem języka F#.
W przypadku interpolacji ciągów w języku F# 11 wyrażenie niesformatowane używa konwersji języka F# string . Jeśli wyrażenie zwróci wartość null, zostanie użyty pusty ciąg. Wcześniejsze kompilatory mogą zoptymalizować niektóre interpolacje tylko ciągów, ale w przeciwnym razie używały formatowania printf; Zobacz Natywna funkcja AOT i interpolacja wartości ciągu , aby uzyskać różnice formatowania.
W przypadku typowanych ciągów interpolowanych ze specyfikatorami formatu (takimi jak %s{expr} lub %d{expr}) konwersja jest zgodna z regułami zdefiniowanymi dla tego określonego specyfikatora formatu.
Aby uniknąć pary nawiasów {} klamrowych, napisz dwa z nich w następujący sposób:
let str = $"A pair of braces: {{}}"
// "A pair of braces: {}"
Wpisane ciągi interpolowane
Ciągi interpolowane mogą również mieć specyfikatory formatu F# w celu wymuszania bezpieczeństwa typu.
let name = "Phillip"
let age = 30
printfn $"Name: %s{name}, Age: %d{age}"
// Error: type mismatch
printfn $"Name: %s{age}, Age: %d{name}"
W poprzednim przykładzie kod błędnie przekazuje age wartość, gdzie name powinna być i na odwrót. Ponieważ ciągi interpolowane używają specyfikatorów formatu, jest to błąd kompilacji zamiast subtelnej usterki środowiska uruchomieniowego.
Ciągi interpolowane dosłownie
Język F# obsługuje ciągi interpolowane na dwa sposoby:
Używanie $@ lub @$ prefiks
Prefiks interpolacji można połączyć z prefiksem $@ ciągu dosłownego w dowolnej kolejności. Ciągi dosłowne ignorują sekwencje ucieczki (z wyjątkiem "" reprezentowania znaku cudzysłowu) i mogą obejmować wiele wierszy. Jest to szczególnie przydatne podczas pracy ze ścieżkami plików lub ciągami zawierającymi ukośniki odwrotne i cudzysłowy.
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"
Używanie cudzysłowów potrójnych
Język F# obsługuje również ciągi interpolowane za pomocą potrójnych cudzysłowów, dzięki czemu można osadzać literały ciągu bez ucieczki.
let age = 30
printfn $"""Name: {"Phillip"}, Age: %d{age}"""
Specyfikatory formatu
Specyfikatory formatu mogą być typu printf lub . Styl net. Specyfikatory stylu printf są objęte formatowaniem zwykłego tekstu umieszczonym przed nawiasami klamrowymi. Przykład:
let pi = $"%0.3f{System.Math.PI}" // "3.142"
let code = $"0x%08x{43962}" // "0x0000abba"
Specyfikator %A formatu jest szczególnie przydatny do tworzenia danych diagnostycznych ustrukturyzowanych danych języka F#.
let data = [0..4]
let output = $"The data is %A{data}" // "The data is [0; 1; 2; 3; 4]"
. Specyfikatory stylu NET są takie, których można używać z elementem String.Format, umieszczonym : po nawiasach klamrowych. Przykład:
let pi = $"{System.Math.PI:N4}" // "3.1416"
let now = $"{System.DateTime.UtcNow:``yyyyMMdd``}" // for example, "20220210"
Jeśli element . Specyfikator stylu NET zawiera nietypowy znak, a następnie można go uniknąć za pomocą podwójnych backticks:
let nowDashes = $"{System.DateTime.UtcNow:``yyyy-MM-dd``}" // for example, "2022-02-10"
Wyrównanie wyrażeń w ciągach interpolowanych
Wyrażenia wyrównane do lewej lub wyrównania do prawej wewnątrz ciągów | interpolowanych i określenie liczby spacji. Poniższy ciąg interpolowany wyrównuje odpowiednio wyrażenia lewe i prawe do lewej i prawej o siedem spacji.
printfn $"""|{"Left",-7}|{"Right",7}|"""
// |Left | Right|
Ciągi interpolowane i FormattableString formatowanie
Można również zastosować formatowanie zgodne z regułami dla elementu 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."
Ponadto ciąg interpolowany może być również sprawdzany jako FormattableString znak za pomocą adnotacji typu:
let frmtStr = $"The speed of light is {speedOfLight:N3} km/s." : FormattableString
// Type: FormattableString
// The speed of light is 299,792.458 km/s.
Należy pamiętać, że adnotacja typu musi znajdować się w samym wyrażeniu ciągu interpolowanego. Język F# nie konwertuje niejawnie ciągu interpolowanego na FormattableString.
Rozszerzona składnia interpolacji ciągów
Począwszy od języka F# 8, gdy pracujesz z tekstem zawierającym już wiele {} znaków lub % , możesz użyć rozszerzonej składni interpolacji ciągów, aby usunąć konieczność ucieczki.
Literały ciągu potrójnego cudzysłowu mogą zaczynać się od wielu $ znaków, co zmienia liczbę nawiasów klamrowych wymaganych do otwarcia i zamknięcia interpolacji.
W tych literałach ciągów { i } znaki nie muszą być ucieczki:
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."""
Liczba znaków potrzebnych % do specyfikatorów formatu ma wpływ w ten sam sposób:
let percent = $$"""50% of 20 is %%.1f{{20m * 0.5m}}"""
// "50% of 20 is 10.0"
Natywna interpolacja AOT i ciągów
Aby sformatować tekst bez aparatu formatowania opartego na odbiciu, użyj interpolacji wartości ciągu z prostymi lub .NET otworami w formacie:
let name = "Ada"
let score = 97.5
let message: string = $"{name}: {score:F1}"
printn message
// Ada: 97.5
Język F# 11 używa konwersji bezpośrednich i System.String.Concat do obsługi większej liczby interpolacji wartości ciągu. Otwór w formacie .NET używa niezmiennego String.Format i pola argumentu. Te zmiany kompilatora obsługują natywną AOT bez konieczności nowoczesnej kompilacji Core; inny kod aplikacji nadal może wymagać odbicia.
Otwory w stylu printf wymagające formatowania wydruku, takie jak %04d{number} lub %A{record}, mogą nadal używać ścieżki opartej na odbiciu. Nagie %s, , %c%d, %ii %M otwory zachowują kontrole typów i unikaj formatowania wydruku. Inne specyfikatory, w tym %u, nie są objęte tą optymalizacją. Interpolacja używana jako wartość różni się również od tej, której typem PrintfFormat wyniku jest string.
Zgodność kultury i formatu
Zwykłe otwory używają konwersji języka F#string; .NET-formatowanie otworów używa niezmiennego formatowania. Aby wygenerować zlokalizowane dane wyjściowe, wybierz jawnie kulturę:
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")
Sprawdź zlokalizowane dane wyjściowe podczas uaktualniania.
FormattableString Zachowuje swoje argumenty dla późniejszego formatowania opartego na dostawcy zamiast podążać tą ścieżką łączenia.
Ostrzeżenie FS3884 identyfikuje niezastosowaną funkcję lub delegata w otworze interpolacji. Zastosuj funkcję, jeśli zamierzasz jej wynik:
let weight () = 12.5m
let text: string = $"Weight: {weight ()} kg"
Zapisywanie wartości w standardowych danych wyjściowych
Aby zapisać wartość bez formatu printf, dodaje print element FSharp.Core 11 i printn. Używają string konwersji; printn dodaje nowy wiersz:
print "Parcels: "
printn 3
W przypadku danych wyjściowych strukturalnych %A użyj formatowania zwykłego tekstu.
Dane wyjściowe rekordu i unii bez odbicia
W programie --reflectionfreejęzyk F# 11 może generować znaczące ToString implementacje dla rekordów i związków zamiast wyświetlać tylko nazwę typu:
type Reading = { Sensor: string; Value: int }
type Outcome = Recorded of Reading | Unavailable
let reading = { Sensor = "north"; Value = 12 }
printn reading
printn (Recorded reading)
Przykładowy projekt włącza flagę. Dane wyjściowe różnią się od %A; typy pól również wymagają odpowiednich ToString implementacji.