String terinterpolasi

String terinterpolasi adalah string yang memungkinkan Anda menyematkan ekspresi F# ke dalamnya. Ini berguna dalam berbagai skenario di mana nilai string dapat berubah berdasarkan hasil nilai atau ekspresi.

Sintaksis

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

Komentar

String terinterpolasi memungkinkan Anda menulis kode di "lubang" di dalam string harfiah. Berikut adalah contoh dasarnya:

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

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

Konten di antara setiap {} pasangan kurung kurawal dapat berupa ekspresi F#apa pun.

Untuk interpolasi bernilai string di F# 11, ekspresi yang tidak diformat menggunakan konversi F#.string Jika ekspresi mengevaluasi ke null, string kosong digunakan. Kompiler sebelumnya dapat mengoptimalkan beberapa interpolasi khusus string, tetapi jika tidak, menggunakan pemformatan printf; lihat AOT asli dan interpolasi bernilai string untuk perbedaan pemformatan.

Untuk string terinterpolasi yang ditik dengan penentu format (seperti %s{expr} atau %d{expr}), konversi mengikuti aturan yang ditentukan untuk penentu format tertentu. Untuk lolos dari {} pasangan kurung kurawal, tulis dua di antaranya seperti:

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

String terinterpolasi yang ditik

String yang diinterpolasi juga dapat memiliki penentu format F# untuk memberlakukan keamanan jenis.

let name = "Phillip"
let age = 30

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

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

Dalam contoh sebelumnya, kode secara keliru meneruskan age nilai di mana name seharusnya, dan sebaliknya. Karena string terinterpolasi menggunakan penentu format, ini adalah kesalahan kompilasi alih-alih bug runtime halus.

String terinterpolasi Verbatim

F# mendukung string terinterpolasi verbatim dengan dua cara:

Menggunakan $@ atau @$ awalan

Anda dapat menggabungkan awalan $ interpolasi dengan awalan @ string verbatim dalam urutan apa pun. String verbatim mengabaikan urutan escape (kecuali untuk "" mewakili tanda kutip) dan dapat mencakup beberapa baris. Ini sangat berguna saat bekerja dengan jalur file atau string yang berisi garis miring terbelakang dan tanda kutip.

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"

Menggunakan tanda kutip tiga kali lipat

F# juga mendukung string terinterpolasi verbatim dengan tanda kutip tiga sehingga Anda dapat menyematkan literal string tanpa melarikan diri.

let age = 30

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

Spesifikasi format

Penentu format dapat berupa gaya cetak atau . Gaya NET. Penentu gaya cetak adalah yang tercakup dalam pemformatan teks biasa, ditempatkan sebelum kurung kurawal. Contohnya:

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

Penentu %A format sangat berguna untuk menghasilkan output diagnostik dari data F# terstruktur.

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

. Penentu gaya NET adalah yang dapat digunakan dengan String.Format, ditempatkan setelah : di dalam kurung kurawal. Contohnya:

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

Jika . Penentu gaya NET berisi karakter yang tidak biasa, maka dapat diloloskan menggunakan backtick ganda:

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

Meratakan ekspresi dalam string terinterpolasi

Anda dapat meratakan kiri atau rata kanan ekspresi di dalam string terinterpolasi dengan | dan spesifikasi berapa banyak spasi. String terinterpolasi berikut ini meratakan ekspresi kiri dan kanan ke kiri dan kanan, masing-masing dengan tujuh spasi.

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

String dan FormattableString pemformatan terinterpolasi

Anda juga dapat menerapkan pemformatan yang mematuhi aturan untuk 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."

Selain itu, string terinterpolasi juga dapat dicentang sebagai FormattableString melalui anotasi jenis:

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

Perhatikan bahwa anotasi jenis harus berada pada ekspresi string terinterpolasi itu sendiri. F# tidak secara implisit mengonversi string terinterpolasi menjadi FormattableString.

Sintaks yang diperluas untuk interpolasi string

Dimulai dengan F# 8, ketika Anda bekerja dengan teks yang berisi beberapa {karakter , } atau % sudah, Anda dapat menggunakan sintaks interpolasi string yang diperluas untuk menghapus kebutuhan untuk melarikan diri.

Literal string kutipan tiga kali dapat dimulai dengan beberapa $ karakter, yang mengubah berapa banyak kurung kurawal yang diperlukan untuk membuka dan menutup interpolasi. Dalam literal string ini, { dan } karakter tidak perlu diloloskan:

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

Jumlah karakter yang % diperlukan untuk penentu format dipengaruhi dengan cara yang sama:

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

AOT asli dan interpolasi bernilai string

Untuk memformat teks tanpa mesin pemformatan berbasis pantulan, gunakan interpolasi bernilai string dengan lubang format biasa atau .NET:

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

F# 11 menggunakan konversi langsung dan System.String.Concat untuk interpolasi yang lebih bernilai string. Lubang berformat .NET menggunakan invarian String.Format dan mengetik argumennya. Perubahan kompilator ini mendukung AOT Asli tanpa memerlukan build Core modern; kode aplikasi lain masih dapat memerlukan refleksi.

Lubang bergaya cetak yang memerlukan pemformatan cetak, seperti %04d{number} atau %A{record}, masih dapat menggunakan jalur berbasis pantulan. Lubang bare %s, %c, %d, %i, dan %M mempertahankan pemeriksaan jenisnya dan menghindari pemformatan printf. Penentu lainnya, termasuk %u, tidak tercakup dalam pengoptimalan tersebut. Interpolasi yang PrintfFormat digunakan sebagai nilai juga berbeda dari yang jenis hasilnya adalah string.

Kompatibilitas budaya dan format

Lubang biasa menggunakan konversi F#sstring; .NET-format lubang menggunakan pemformatan invarian. Untuk menghasilkan output yang dilokalkan, pilih budaya secara eksplisit:

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

Periksa output yang dilokalkan saat meningkatkan. FormattableString mempertahankan argumennya untuk pemformatan berbasis penyedia nanti alih-alih mengikuti jalur perangkaian ini.

Peringatan FS3884 mengidentifikasi fungsi yang tidak diterapkan atau mendelegasikan dalam lubang interpolasi. Terapkan fungsi jika Anda menginginkan hasilnya:

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

Menulis nilai ke output standar

Untuk menulis nilai tanpa format printf, FSharp.Core 11 menambahkan print dan printn. Mereka menggunakan string konversi; printn menambahkan baris baru:

print "Parcels: "
printn 3

Untuk output struktural %A , gunakan pemformatan teks biasa.

Output rekaman dan union tanpa refleksi

Dengan --reflectionfree, F# 11 dapat menghasilkan implementasi yang bermakna ToString untuk rekaman dan penyatuan alih-alih hanya menampilkan nama jenis:

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

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

Proyek sampel memungkinkan bendera. Output berbeda dari %A; jenis bidang juga membutuhkan implementasi yang sesuai ToString .

Lihat juga