Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
F# mendukung pemformatan teks biasa yang dicentang jenis menggunakan printffungsi terkait , printfn, sprintf, dan .
Contohnya,
dotnet fsi
> printfn "Hello %s, %d + %d is %d" "world" 2 2 (2+2);;
memberikan output
Hello world, 2 + 2 is 4
F# juga memungkinkan nilai terstruktur diformat sebagai teks biasa. Misalnya, pertimbangkan contoh berikut yang memformat output sebagai tampilan tuple seperti matriks.
dotnet fsi
> printfn "%A" [ for i in 1 .. 5 -> [ for j in 1 .. 5 -> (i, j) ] ];;
[[(1, 1); (1, 2); (1, 3); (1, 4); (1, 5)];
[(2, 1); (2, 2); (2, 3); (2, 4); (2, 5)];
[(3, 1); (3, 2); (3, 3); (3, 4); (3, 5)];
[(4, 1); (4, 2); (4, 3); (4, 4); (4, 5)];
[(5, 1); (5, 2); (5, 3); (5, 4); (5, 5)]]
Pemformatan teks biasa terstruktur diaktifkan saat Anda menggunakan %A format dalam printf memformat string.
Ini juga diaktifkan saat memformat output nilai dalam interaktif F#, di mana output menyertakan informasi tambahan dan juga dapat disesuaikan.
Pemformatan teks biasa juga dapat diamati melalui panggilan apa pun ke x.ToString() pada nilai union dan record F#, termasuk yang terjadi secara implisit dalam penelusuran kesalahan, pengelogan, dan alat lainnya.
Memeriksa printfstring -format
Kesalahan waktu kompilasi akan dilaporkan jika printf fungsi pemformatan digunakan dengan argumen yang tidak cocok dengan penentu format cetak dalam string format. Contohnya,
sprintf "Hello %s" (2+2)
memberikan output
sprintf "Hello %s" (2+2)
----------------------^
stdin(3,25): error FS0001: The type 'string' does not match the type 'int'
Secara teknis, saat menggunakan printf dan fungsi terkait lainnya, aturan khusus dalam kompilator F# memeriksa string harfiah yang diteruskan sebagai string format, memastikan argumen berikutnya yang diterapkan adalah jenis yang benar agar sesuai dengan penentu format yang digunakan.
Penentu format untuk printf
Spesifikasi format untuk printf format adalah string dengan % penanda yang menunjukkan format. Tempat penampung format terdiri dari %[flags][width][.precision][type] tempat jenis ditafsirkan sebagai berikut:
| Penentu format | Jenis | Komentar |
|---|---|---|
%b |
bool(System.Boolean) |
Diformat sebagai true atau false |
%s |
string(System.String) |
Diformat sebagai isinya yang tidak dilewati |
%c |
char(System.Char) |
Diformat sebagai karakter harfiah |
%d, %i |
jenis bilangan bulat dasar | Diformat sebagai bilangan bulat desimal, ditandatangani jika jenis bilangan bulat dasar ditandatangani |
%u |
jenis bilangan bulat dasar | Diformat sebagai bilangan bulat desimal yang tidak ditandatangani |
%x, %X |
jenis bilangan bulat dasar | Diformat sebagai angka heksadesimal yang tidak ditandatangani (a-f atau A-F untuk digit heksadesimal masing-masing) |
%o |
jenis bilangan bulat dasar | Diformat sebagai angka oktal yang tidak ditandatangani |
%B |
jenis bilangan bulat dasar | Diformat sebagai angka biner yang tidak ditandatangani |
%e, %E |
jenis titik mengambang dasar | Diformat sebagai nilai yang ditandatangani memiliki formulir [-]d.dddde[sign]ddd di mana d adalah digit desimal tunggal, dddd adalah satu atau beberapa digit desimal, ddd tepat tiga digit desimal, dan tanda atau +- |
%f, %F |
jenis titik mengambang dasar | Diformat sebagai nilai yang ditandatangani memiliki formulir [-]dddd.dddd, di mana dddd adalah satu atau beberapa digit desimal. Jumlah digit sebelum titik desimal tergantung pada besarnya angka, dan jumlah digit setelah titik desimal tergantung pada presisi yang diminta. |
%g, %G |
jenis titik mengambang dasar | Diformat menggunakan sebagai nilai bertanda tangan yang dicetak dalam %f atau %e format, mana yang lebih ringkas untuk nilai dan presisi yang diberikan. |
%M |
nilai decimal (System.Decimal) |
Diformat menggunakan penentu "G" format untuk System.Decimal.ToString(format) |
%O |
nilai apa pun | Diformat dengan metinju objek dan memanggil metodenya System.Object.ToString() |
%A |
nilai apa pun | Diformat menggunakan pemformatan teks biasa terstruktur dengan pengaturan tata letak default |
%a |
nilai apa pun | Memerlukan dua argumen: fungsi pemformatan yang menerima parameter konteks dan nilai, dan nilai tertentu untuk dicetak |
%t |
nilai apa pun | Memerlukan satu argumen: fungsi pemformatan yang menerima parameter konteks yang menghasilkan atau mengembalikan teks yang sesuai |
%% |
(tidak ada) | Tidak memerlukan argumen dan mencetak tanda persen biasa: % |
Jenis bilangan bulat dasar adalah (), (), (System.Int16), int16 (), int32uint16 (System.Int32System.UInt16), uint32 (System.UInt32), int64 (System.Int64), uint64 (), (System.UInt64), nativeint (System.IntPtr), dan unativeint ().System.UIntPtrSystem.SBytesbyteSystem.Bytebyte
Jenis titik mengambang dasar adalah float (System.Double), float32 (System.Single), dan decimal (System.Decimal).
Lebar opsional adalah bilangan bulat yang menunjukkan lebar hasil minimal. Misalnya, %6d mencetak bilangan bulat, mengawalinya dengan spasi untuk mengisi setidaknya enam karakter. Jika lebar adalah *, maka argumen bilangan bulat tambahan diambil untuk menentukan lebar yang sesuai.
Bendera yang valid adalah:
| Bendera | Efek |
|---|---|
0 |
Tambahkan nol alih-alih spasi untuk membentuk lebar yang diperlukan |
- |
Kiri membenarkan hasil dalam lebar yang ditentukan |
+ |
+ Tambahkan karakter jika angka positif (untuk mencocokkan - tanda negatif) |
| karakter spasi | Tambahkan spasi tambahan jika angka positif (agar cocok dengan tanda '-' untuk negatif) |
Bendera printf # tidak valid dan kesalahan waktu kompilasi akan dilaporkan jika digunakan.
Nilai diformat menggunakan budaya invarian. Pengaturan budaya tidak relevan dengan printf pemformatan kecuali ketika memengaruhi hasil %O dan %A pemformatan. Untuk informasi selengkapnya, lihat pemformatan teks biasa terstruktur.
%A Format
Penentu %A format digunakan untuk memformat nilai dengan cara yang dapat dibaca manusia, dan juga dapat berguna untuk melaporkan informasi diagnostik.
Nilai primitif
Saat memformat teks biasa menggunakan penentu %A , nilai numerik F# diformat dengan akhiran dan budaya invariannya. Nilai titik mengambang diformat menggunakan 10 tempat presisi titik mengambang. Contohnya,
printfn "%A" (1L, 3n, 5u, 7, 4.03f, 5.000000001, 5.0000000001)
Menghasilkan
(1L, 3n, 5u, 7, 4.03000021f, 5.000000001, 5.0)
Saat menggunakan penentu %A , string diformat menggunakan tanda kutip. Kode escape tidak ditambahkan dan sebaliknya karakter mentah dicetak. Contohnya,
printfn "%A" ("abc", "a\tb\nc\"d")
Menghasilkan
("abc", "a b
c"d")
Nilai .NET
Saat memformat teks biasa menggunakan penentu %A , objek .NET non-F# diformat dengan menggunakan x.ToString() pengaturan default .NET yang diberikan oleh System.Globalization.CultureInfo.CurrentCulture dan System.Globalization.CultureInfo.CurrentUICulture. Contohnya,
open System.Globalization
let date = System.DateTime(1999, 12, 31)
CultureInfo.CurrentCulture <- CultureInfo.GetCultureInfo("de-DE")
printfn "Culture 1: %A" date
CultureInfo.CurrentCulture <- CultureInfo.GetCultureInfo("en-US")
printfn "Culture 2: %A" date
Menghasilkan
Culture 1: 31.12.1999 00:00:00
Culture 2: 12/31/1999 12:00:00 AM
Nilai terstruktur
Saat memformat teks biasa menggunakan penentu %A , indentasi blok digunakan untuk daftar F# dan tuple. Ini ditunjukkan dalam contoh sebelumnya.
Struktur array juga digunakan, termasuk array multi-dimensi. Array dimensi tunggal ditampilkan dengan [| ... |] sintaks. Contohnya,
printfn "%A" [| for i in 1 .. 20 -> (i, i*i) |]
Menghasilkan
[|(1, 1); (2, 4); (3, 9); (4, 16); (5, 25); (6, 36); (7, 49); (8, 64); (9, 81);
(10, 100); (11, 121); (12, 144); (13, 169); (14, 196); (15, 225); (16, 256);
(17, 289); (18, 324); (19, 361); (20, 400)|]
Lebar cetak default adalah 80. Lebar ini dapat dikustomisasi dengan menggunakan lebar cetak dalam penentu format. Contohnya,
printfn "%10A" [| for i in 1 .. 5 -> (i, i*i) |]
printfn "%20A" [| for i in 1 .. 5 -> (i, i*i) |]
printfn "%50A" [| for i in 1 .. 5 -> (i, i*i) |]
Menghasilkan
[|(1, 1);
(2, 4);
(3, 9);
(4, 16);
(5, 25)|]
[|(1, 1); (2, 4);
(3, 9); (4, 16);
(5, 25)|]
[|(1, 1); (2, 4); (3, 9); (4, 16); (5, 25)|]
Menentukan lebar cetak 0 menghasilkan tidak ada lebar cetak yang digunakan. Satu baris teks akan dihasilkan, kecuali jika string yang disematkan dalam output berisi hentian baris. Misalnya
printfn "%0A" [| for i in 1 .. 5 -> (i, i*i) |]
printfn "%0A" [| for i in 1 .. 5 -> "abc\ndef" |]
Menghasilkan
[|(1, 1); (2, 4); (3, 9); (4, 16); (5, 25)|]
[|"abc
def"; "abc
def"; "abc
def"; "abc
def"; "abc
def"|]
Batas kedalaman 4 digunakan untuk nilai urutan (IEnumerable), yang ditampilkan sebagai seq { ...}. Batas kedalaman 100 digunakan untuk nilai daftar dan array.
Contohnya,
printfn "%A" (seq { for i in 1 .. 10 -> (i, i*i) })
Menghasilkan
seq [(1, 1); (2, 4); (3, 9); (4, 16); ...]
Indentasi blok juga digunakan untuk struktur catatan publik dan nilai serikat. Contohnya,
type R = { X : int list; Y : string list }
printfn "%A" { X = [ 1;2;3 ]; Y = ["one"; "two"; "three"] }
Menghasilkan
{ X = [1; 2; 3]
Y = ["one"; "two"; "three"] }
Jika %+A digunakan, maka struktur pribadi rekaman dan serikat kerja juga diungkapkan dengan menggunakan pantulan. Misalnya
type internal R =
{ X : int list; Y : string list }
override _.ToString() = "R"
let internal data = { X = [ 1;2;3 ]; Y = ["one"; "two"; "three"] }
printfn "external view:\n%A" data
printfn "internal view:\n%+A" data
Menghasilkan
external view:
R
internal view:
{ X = [1; 2; 3]
Y = ["one"; "two"; "three"] }
Nilai besar, siklik, atau berlapis dalam
Nilai terstruktur besar diformat ke jumlah simpul objek keseluruhan maksimum 10000.
Nilai berlapis dalam diformat ke kedalaman 100. Dalam kedua kasus ... digunakan untuk elide beberapa output. Contohnya,
type Tree =
| Tip
| Node of Tree * Tree
let rec make n =
if n = 0 then
Tip
else
Node(Tip, make (n-1))
printfn "%A" (make 1000)
menghasilkan output besar dengan beberapa bagian yang dilewati:
Node(Tip, Node(Tip, ....Node (..., ...)...))
Siklus terdeteksi dalam grafik objek dan ... digunakan di tempat-tempat di mana siklus terdeteksi. Misalnya
type R = { mutable Links: R list }
let r = { Links = [] }
r.Links <- [r]
printfn "%A" r
Menghasilkan
{ Links = [...] }
Nilai malas, null, dan fungsi
Nilai malas dicetak sebagai Value is not created atau teks yang setara ketika nilai belum dievaluasi.
Nilai null dicetak sebagai null kecuali jenis statis dari nilai ditentukan sebagai jenis gabungan di mana null adalah representasi yang diizinkan.
Nilai fungsi F# dicetak sebagai nama penutup yang dihasilkan secara internal, misalnya, <fun:it@43-7>.
Mengkustomisasi pemformatan teks biasa dengan StructuredFormatDisplay
Saat menggunakan penentu %A , kehadiran StructuredFormatDisplay atribut pada deklarasi jenis dihormati. Ini dapat digunakan untuk menentukan teks pengganti dan properti untuk menampilkan nilai. Contohnya:
[<StructuredFormatDisplay("Counts({Clicks})")>]
type Counts = { Clicks:int list}
printfn "%20A" {Clicks=[0..20]}
Menghasilkan
Counts([0; 1; 2; 3;
4; 5; 6; 7;
8; 9; 10; 11;
12; 13; 14;
15; 16; 17;
18; 19; 20])
Mengkustomisasi pemformatan teks biasa dengan menimpa ToString
Implementasi ToString default dapat diamati dalam pemrograman F#. Seringkali, hasil default tidak cocok untuk digunakan dalam tampilan informasi yang menghadap programmer atau output pengguna, dan akibatnya umum untuk mengambil alih implementasi default.
Secara default, jenis rekaman dan serikat F# mengambil alih implementasi ToString dengan implementasi yang menggunakan sprintf "%+A". Contohnya,
type Counts = { Clicks:int list }
printfn "%s" ({Clicks=[0..10]}.ToString())
Menghasilkan
{ Clicks = [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10] }
Untuk jenis kelas, tidak ada implementasi ToString default yang disediakan dan default .NET digunakan, yang melaporkan nama jenis. Contohnya,
type MyClassType(clicks: int list) =
member _.Clicks = clicks
let data = [ MyClassType([1..5]); MyClassType([1..5]) ]
printfn "Default structured print gives this:\n%A" data
printfn "Default ToString gives:\n%s" (data.ToString())
Menghasilkan
Default structured print gives this:
[MyClassType; MyClassType]
Default ToString gives:
[MyClassType; MyClassType]
Menambahkan penimpaan untuk ToString dapat memberikan pemformatan yang lebih baik.
type MyClassType(clicks: int list) =
member _.Clicks = clicks
override _.ToString() = sprintf "MyClassType(%0A)" clicks
let data = [ MyClassType([1..5]); MyClassType([1..5]) ]
printfn "Now structured print gives this:\n%A" data
printfn "Now ToString gives:\n%s" (data.ToString())
Menghasilkan
Now structured print gives this:
[MyClassType([1; 2; 3; 4; 5]); MyClassType([1; 2; 3; 4; 5])]
Now ToString gives:
[MyClassType([1; 2; 3; 4; 5]); MyClassType([1; 2; 3; 4; 5])]
Mengkustomisasi pemformatan teks biasa dengan StructuredFormatDisplay dan ToString
Untuk mencapai pemformatan yang konsisten untuk %A penentu format dan %O , gabungkan penggunaan StructuredFormatDisplay dengan penimpaan ToString. Contohnya,
[<StructuredFormatDisplay("{DisplayText}")>]
type MyRecord =
{
a: int
}
member this.DisplayText = this.ToString()
override _.ToString() = "Custom ToString"
Mengevaluasi definisi berikut
let myRec = { a = 10 }
let myTuple = (myRec, myRec)
let s1 = sprintf $"{myRec}"
let s2 = sprintf $"{myTuple}"
let s3 = sprintf $"%A{myTuple}"
let s4 = sprintf $"{[myRec; myRec]}"
let s5 = sprintf $"%A{[myRec; myRec]}"
memberikan teks
val myRec: MyRecord = Custom ToString
val myTuple: MyRecord * MyRecord = (Custom ToString, Custom ToString)
val s1: string = "Custom ToString"
val s2: string = "(Custom ToString, Custom ToString)"
val s3: string = "(Custom ToString, Custom ToString)"
val s4: string = "[Custom ToString; Custom ToString]"
val s5: string = "[Custom ToString; Custom ToString]"
Penggunaan StructuredFormatDisplay dengan properti pendukung DisplayText berarti fakta bahwa myRec adalah jenis catatan struktural diabaikan selama pencetakan terstruktur, dan penimpaan ToString() lebih disukai dalam semua keadaan.
Implementasi System.IFormattable antarmuka dapat ditambahkan untuk penyesuaian lebih lanjut di hadapan spesifikasi format .NET.
F# Pencetakan terstruktur interaktif
F# Interactive (dotnet fsi) menggunakan versi pemformatan teks biasa terstruktur yang diperluas untuk melaporkan nilai dan memungkinkan penyesuaian tambahan. Untuk informasi selengkapnya, lihat F# Interactive.
Menyesuaikan tampilan debug
Debugger untuk .NET menghormati penggunaan atribut seperti DebuggerDisplay dan DebuggerTypeProxy, dan ini memengaruhi tampilan objek terstruktur di jendela inspeksi debugger.
Pengkompilasi F# secara otomatis menghasilkan atribut ini untuk jenis penyatuan dan rekaman yang diskriminasi, tetapi bukan jenis kelas, antarmuka, atau struktur.
Atribut ini diabaikan dalam pemformatan teks biasa F#, tetapi dapat berguna untuk mengimplementasikan metode ini untuk meningkatkan tampilan saat men-debug jenis F#.