Egyszerű szövegformázás
Az F# támogatja az egyszerű szövegek gépelt formázását a , printfn
, sprintf
és a kapcsolódó függvények használatávalprintf
.
Például:
dotnet fsi
> printfn "Hello %s, %d + %d is %d" "world" 2 2 (2+2);;
adja meg a kimenetet
Hello world, 2 + 2 is 4
Az F# lehetővé teszi a strukturált értékek egyszerű szövegként való formázását is. Vegyük például az alábbi példát, amely a kimenetet mátrixszerű ugródékként formázja.
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)]]
A strukturált egyszerű szövegformázás akkor aktiválódik, ha a formázási sztringekben printf
használja a %A
formátumot.
Az F# interaktív értékeinek formázásakor is aktiválódik, ahol a kimenet további információkat tartalmaz, és további testreszabható.
Az egyszerű szövegformázás az F# összevonási és rekordértékekre irányuló hívásokon x.ToString()
keresztül is megfigyelhető, beleértve azokat is, amelyek implicit módon fordulnak elő a hibakeresésben, a naplózásban és az egyéb eszközökben.
-format sztringek printf
ellenőrzése
Fordítási időt jelző hiba jelenik meg, ha egy printf
formázási függvény olyan argumentummal van használva, amely nem egyezik a formátumsztringben szereplő printf formátumjelölőkkel. Például:
sprintf "Hello %s" (2+2)
adja meg a kimenetet
sprintf "Hello %s" (2+2)
----------------------^
stdin(3,25): error FS0001: The type 'string' does not match the type 'int'
Technikailag az printf
F#-fordító egy speciális szabálya ellenőrzi a formátumsztringként átadott sztringkonstanst, biztosítva, hogy az ezt követő argumentumok a megfelelő típusúak legyenek a használt formátumkijelölőknek megfelelően.
Formátumjelölők a következőhöz: printf
A formátumok formátumspecifikációi printf
a formátumot jelző jelölőkkel rendelkező %
sztringek. A helyőrzők formázása %[flags][width][.precision][type]
az alábbiak szerint értelmezi a típust:
Formátumkijelölő | Típus(ok) | Megjegyzések |
---|---|---|
%b |
bool (System.Boolean ) |
Formázott vagy true formázott false |
%s |
string (System.String ) |
Formázott tartalomként |
%c |
char (System.Char ) |
Karakterkonstansként formázva |
%d , %i |
alapszintű egész számtípus | Decimális egész számként formázva, aláírva, ha az egyszerű egész szám típusa alá van írva |
%u |
alapszintű egész számtípus | Nem aláírt decimális egész számként formázva |
%x , %X |
alapszintű egész számtípus | Nem aláírt hexadecimális számként formázva (a-f vagy A-F a hexa számjegyekhez) |
%o |
alapszintű egész számtípus | Nem aláírt oktális számként formázva |
%B |
alapszintű egész számtípus | Nem aláírt bináris számként formázva |
%e , %E |
alapszintű lebegőpontos típus | Aláírt értékként formázva, amelyben a [-]d.dddde[sign]ddd d egy tizedesjegy, a dddd egy vagy több tizedesjegy, a ddd pedig pontosan három tizedesjegy, a jel + pedig vagy - |
%f , %F |
alapszintű lebegőpontos típus | Az űrlapot [-]dddd.dddd aláíró értékként formázva, ahol dddd egy vagy több tizedesjegy található. A tizedesvessző előtti számjegyek száma a szám nagyságától függ, a tizedesvessző utáni számjegyek száma pedig a kért pontosságtól függ. |
%g , %G |
alapszintű lebegőpontos típus | Formázva nyomtatott vagy %e formázott aláírt értékként%f , attól függően, hogy melyik kompaktabb az adott értékhez és pontossághoz. |
%M |
a decimal (System.Decimal ) érték |
Formázás a "G" következő formátumjelölő használatával: System.Decimal.ToString(format) |
%O |
bármilyen érték | Formázva az objektum dobozolásával és metódusának meghívásával System.Object.ToString() |
%A |
bármilyen érték | Formázva strukturált egyszerű szöveges formázással az alapértelmezett elrendezési beállításokkal |
%a |
bármilyen érték | Két argumentumot igényel: a környezeti paramétert és az értéket elfogadó formázási függvényt, valamint a nyomtatandó értéket |
%t |
bármilyen érték | Egy argumentumot igényel: egy olyan formázási függvényt, amely elfogad egy környezeti paramétert, amely vagy kimenetet ad vissza, vagy a megfelelő szöveget adja vissza |
%% |
(nincs) | Nincs szükség argumentumokra, és egyszerű százalékjelet nyomtat: % |
Az egyszerű egész számtípusok a következők byte
: (System.Byte
), sbyte
(System.SByte
), (System.Int16
), int16
(), uint16
int32
(System.UInt16
), (System.Int32
System.UInt32
), uint32
(System.Int64
), int64
(System.UInt64
), nativeint
uint64
(System.IntPtr
) és unativeint
().System.UIntPtr
Az alapszintű lebegőpontos típusok a float
következők: (System.Double
), float32
(System.Single
) és decimal
(System.Decimal
).
Az opcionális szélesség egy egész szám, amely az eredmény minimális szélességét jelzi. Például %6d
kinyomtat egy egész számot, és szóközökkel előtaggal alakítja ki, hogy legalább hat karaktert töltsön ki. Ha szélesség, *
akkor a megfelelő szélesség megadásához egy további egész szám argumentumot kell megadnia.
Az érvényes jelzők a következők:
Jelölő | Hatály |
---|---|
0 |
Szóközök helyett nullák hozzáadása a szükséges szélesség létrehozásához |
- |
Bal oldali sorkizárás az eredményhez a megadott szélességen belül |
+ |
Adjon hozzá egy karaktert + , ha a szám pozitív (a negatívok előjelének megfelelően - ) |
szóköz karakter | Adjon hozzá egy extra szóközt, ha a szám pozitív (a negatívok "-" jelének megfelelően) |
A nyomtatójelző #
érvénytelen, és a rendszer fordítási időt jelző hibát jelez, ha használja.
Az értékek invariáns kultúrával vannak formázva. A kulturális beállítások a formázás szempontjából irrelevánsak printf
, kivéve, ha azok hatással vannak az eredményekre %O
és %A
a formázásra. További információ: strukturált egyszerű szövegformázás.
%A
Formázás
A %A
formátumkijelölő az értékek emberi olvasható módon történő formázására szolgál, és diagnosztikai információk jelentéséhez is hasznos lehet.
Primitív értékek
Ha egyszerű szöveget formáz a kijelölővel, az %A
F# numerikus értékek az utótagjukkal és az invariáns kultúrájukkal vannak formázva. A lebegőpontos értékek 10 lebegőpontos pontosságú hely használatával vannak formázva. Például:
printfn "%A" (1L, 3n, 5u, 7, 4.03f, 5.000000001, 5.0000000001)
Termel
(1L, 3n, 5u, 7, 4.03000021f, 5.000000001, 5.0)
A kijelölő használatakor a %A
sztringek idézőjelek használatával vannak formázva. A rendszer nem adja hozzá a feloldókódokat, hanem a nyers karaktereket nyomtatja ki. Például:
printfn "%A" ("abc", "a\tb\nc\"d")
Termel
("abc", "a b
c"d")
.NET-értékek
Ha egyszerű szöveget formáz a kijelölővel, a %A
nem F# .NET-objektumok formázása x.ToString()
a .NET által megadott System.Globalization.CultureInfo.CurrentCulture
alapértelmezett beállításokkal történik System.Globalization.CultureInfo.CurrentUICulture
. Például:
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
Termel
Culture 1: 31.12.1999 00:00:00
Culture 2: 12/31/1999 12:00:00 AM
Strukturált értékek
Ha egyszerű szöveget formáz a kijelölővel, akkor az %A
F#-listákhoz és -listákhoz blokkbehúzást használ. Ez az előző példában látható.
A tömbök struktúráját is használják, beleértve a többdimenziós tömböket is. Az egydimenziós tömbök szintaxissal [| ... |]
jelennek meg. Például:
printfn "%A" [| for i in 1 .. 20 -> (i, i*i) |]
Termel
[|(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)|]
Az alapértelmezett nyomtatási szélesség 80. Ezt a szélességet a formátumkijelölő nyomtatási szélességével szabhatja testre. Például:
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) |]
Termel
[|(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)|]
Ha 0 nyomtatási szélességet ad meg, az nem használ nyomtatási szélességet. Egyetlen sornyi szöveg jelenik meg, kivéve, ha a kimenet beágyazott sztringjei sortöréseket tartalmaznak. Példa:
printfn "%0A" [| for i in 1 .. 5 -> (i, i*i) |]
printfn "%0A" [| for i in 1 .. 5 -> "abc\ndef" |]
Termel
[|(1, 1); (2, 4); (3, 9); (4, 16); (5, 25)|]
[|"abc
def"; "abc
def"; "abc
def"; "abc
def"; "abc
def"|]
A rendszer 4 mélységi korlátot használ a sorozat (IEnumerable
) értékekhez, amelyek a seq { ...}
következőképpen jelennek meg: . A lista- és tömbértékekhez 100-ra vonatkozó mélységi korlátot használunk.
Például:
printfn "%A" (seq { for i in 1 .. 10 -> (i, i*i) })
Termel
seq [(1, 1); (2, 4); (3, 9); (4, 16); ...]
A blokkbehúzás a nyilvános rekord és az egyesítő értékek szerkezetéhez is használható. Például:
type R = { X : int list; Y : string list }
printfn "%A" { X = [ 1;2;3 ]; Y = ["one"; "two"; "three"] }
Termel
{ X = [1; 2; 3]
Y = ["one"; "two"; "three"] }
Ha %+A
használják, akkor a rekordok és az egyesítők privát struktúrája is tükröződés segítségével tárul fel. Példa:
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
Termel
external view:
R
internal view:
{ X = [1; 2; 3]
Y = ["one"; "two"; "three"] }
Nagy, ciklikus vagy mélyen beágyazott értékek
A nagyméretű strukturált értékek legfeljebb 10000 objektumcsomópont-számra vannak formázva.
A mélyen beágyazott értékek 100-ra vannak formázva. Mindkét esetben ...
a kimenet egy részének adására szolgál. Például:
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)
nagy kimenetet hoz létre, amelynek egyes részei rendezettek:
Node(Tip, Node(Tip, ....Node (..., ...)...))
A ciklusok az objektumgráfokban észlelhetők, és ...
olyan helyeken használatosak, ahol a ciklusok észlelhetők. Példa:
type R = { mutable Links: R list }
let r = { Links = [] }
r.Links <- [r]
printfn "%A" r
Termel
{ Links = [...] }
Lusta, null és függvényértékek
A lusta értékek akkor lesznek nyomtatva szövegként vagy azzal egyenértékűként Value is not created
, ha az értéket még nem értékelték ki.
A null értékeket a rendszer úgy nyomtatja ki, mintha null
az érték statikus típusa egy egyesítési típus lenne, ahol null
engedélyezett a megjelenítés.
Az F# függvény értékeit a rendszer a belsőleg létrehozott zárónévként nyomtatja ki, <fun:it@43-7>
például.
Egyszerű szövegformázás testreszabása a következővel: StructuredFormatDisplay
A megadó használatakor az %A
attribútum jelenléte StructuredFormatDisplay
a típusdeklarációkban tiszteletben van tartva. Ez használható helyettesítő szöveg és tulajdonság megadására egy érték megjelenítéséhez. Példa:
[<StructuredFormatDisplay("Counts({Clicks})")>]
type Counts = { Clicks:int list}
printfn "%20A" {Clicks=[0..20]}
Termel
Counts([0; 1; 2; 3;
4; 5; 6; 7;
8; 9; 10; 11;
12; 13; 14;
15; 16; 17;
18; 19; 20])
Egyszerű szövegformázás testreszabása felülírással ToString
Az alapértelmezett implementáció ToString
az F#-programozásban figyelhető meg. Az alapértelmezett eredmények gyakran nem alkalmasak sem a programozók által megjelenített információk megjelenítésére, sem a felhasználói kimenetre, ezért gyakran előfordul, hogy felülbírálják az alapértelmezett implementációt.
Alapértelmezés szerint az F# rekord- és egyesítőtípusok felülbírálják a végrehajtást ToString
egy olyan implementációval, amely azokat használja sprintf "%+A"
. Például:
type Counts = { Clicks:int list }
printfn "%s" ({Clicks=[0..10]}.ToString())
Termel
{ Clicks = [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10] }
Az osztálytípusok esetében nincs megadva alapértelmezett implementáció ToString
, és a .NET alapértelmezett értéke van használatban, amely a típus nevét jelenti. Például:
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())
Termel
Default structured print gives this:
[MyClassType; MyClassType]
Default ToString gives:
[MyClassType; MyClassType]
A felülbírálás ToString
hozzáadása jobb formázást biztosíthat.
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())
Termel
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])]
Egyszerű szövegformázás testreszabása és StructuredFormatDisplay
ToString
A formázási és %O
formázási definiálók egységes formázásának %A
StructuredFormatDisplay
eléréséhez kombinálja a használatot a következő felülbírálásávalToString
: . Például:
[<StructuredFormatDisplay("{DisplayText}")>]
type MyRecord =
{
a: int
}
member this.DisplayText = this.ToString()
override _.ToString() = "Custom ToString"
Az alábbi definíciók kiértékelése
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]}"
adja meg a szöveget
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]"
StructuredFormatDisplay
A segédtulajdonság DisplayText
használata azt jelenti, hogy a myRec
szerkezeti rekordtípust a rendszer a strukturált nyomtatás során figyelmen kívül hagyja, és a felülbírálást ToString()
minden körülmények között előnyben részesíti.
A felület implementációja System.IFormattable
hozzáadható a további testreszabáshoz a .NET formátum specifikációinak jelenlétében.
F# Interaktív strukturált nyomtatás
Az F# Interactive (dotnet fsi
) a strukturált egyszerű szövegformázás kiterjesztett verzióját használja az értékek jelentéséhez, és további testreszabhatóságot tesz lehetővé. További információ: F# Interactive.
Hibakeresési kijelzők testreszabása
A .NET hibakeresői tiszteletben tartják az olyan attribútumok használatát, mint DebuggerDisplay
az és DebuggerTypeProxy
, és ezek befolyásolják az objektumok strukturált megjelenítését a hibakereső ellenőrzőablakaiban.
Az F#-fordító automatikusan létrehozta ezeket az attribútumokat a diszkriminált egyesítési és rekordtípusokhoz, osztály-, felület- és szerkezettípusokhoz azonban nem.
Ezeket az attribútumokat figyelmen kívül hagyja az F# egyszerű szöveges formázása, de az F#-típusok hibakeresésekor hasznos lehet ezeket a metódusokat implementálni a megjelenítés javítása érdekében.