Megosztás a következőn keresztül:


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 printfellenő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.ddddaláí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 (), uint16int32 (System.UInt16), (System.Int32System.UInt32), uint32 (System.Int64), int64 (System.UInt64), nativeintuint64 (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 StructuredFormatDisplayToString

A formázási és %O formázási definiálók egységes formázásának %AStructuredFormatDisplay 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.

Lásd még