Udostępnij za pośrednictwem


Literały

W tym artykule przedstawiono tabelę przedstawiającą sposób określania typu literału w języku F#.

Typy literałów

W poniższej tabeli przedstawiono typy literałów w języku F#. Znaki reprezentujące cyfry w notacji szesnastkowej nie są wrażliwe na wielkość liter; znaki identyfikujące typ są wrażliwe na wielkość liter.

Typ Opis Sufiks lub prefiks Przykłady
sbyte znakowa 8-bitowa liczba całkowita y 86y

0b00000101y
bajt niepodpisany 8-bitowy numer naturalny uy 86uy

0b00000101uy
int16 16-bitowa liczba całkowita ze znakiem s 86s
uint16 niepodpisany 16-bitowy numer naturalny nas 86us
Int

int32
ze znakiem 32-bitowej liczby całkowitej l lub brak 86

86l
uint

uint32
niepodpisany 32-bitowy numer naturalny u lub ul 86u

86ul
nativeint natywny wskaźnik do podpisanego numeru naturalnego n 123n
unativeint natywny wskaźnik jako nieznakowana liczba naturalna jeden 0x00002D3Fun
int64 znakowana 64-bitowa liczba całkowita L 86L
uint64 niepodpisany 64-bitowy numer naturalny UL 86UL
pojedynczy, float32 32-bitowa liczba zmiennoprzecinkowa F lub f 4.14F lub 4.14f lub infinityf lub -infinityf
Lf 0x00000000lf
spławik; podwójny 64-bitowa liczba zmiennoprzecinkowa żaden 4.14 lub 2.3E+32, 2.3e+32 lub infinity lub -infinity
LF 0x0000000000000000LF
bigint Liczba całkowita nie ogranicza się do reprezentacji 64-bitowej Ja 9999999999999999999999999999I
dziesiętny liczba ułamkowa reprezentowana jako stały punkt lub liczba racjonalna M lub m 0.7833M lub 0.7833m
Char Znak Unicode żaden 'a' lub '\u0061'
Struna Ciąg Unicode żaden "text\n"

lub

@"c:\filename"

lub

"""<book title="Paradise Lost">"""

lub

"string1" + "string2"

Zobacz również Łańcuchy.
bajt Znak ASCII B 'a'B
byte[] Ciąg ASCII B "text"B
Ciąg lub bajt[] ciąg dosłowny prefiks @ @"\\server\share" (Unicode)

@"\\server\share"B (ASCII)

Nazwane literały

Wartości, które mają być stałymi, można oznaczyć atrybutem Literal.

Ten atrybut ma wpływ na kompilowanie wartości jako stałej. W poniższym przykładzie zarówno x, jak i y poniżej są niezmienne wartości, ale x są oceniane w czasie wykonywania, natomiast y jest stałą czasu kompilacji.

let x = "a" + "b" // evaluated at run-time

[<Literal>]
let y = "a" + "b" // evaluated at compile-time

Notatka

Funkcji nie można używać do obliczania wartości [<Literal>], ponieważ literały muszą być określane w czasie kompilacji i nie mogą zależeć od oceny środowiska uruchomieniowego.

Dlaczego funkcje nie mogą obliczać literałów

Atrybut [<Literal>] wymaga, aby wartości są znane w czasie kompilacji. Funkcje, nawet jeśli wydają się generować stałe dane wyjściowe, są oceniane w czasie wykonywania, co czyni je nieodpowiednimi dla [<Literal>]. To ograniczenie gwarantuje, że literały mogą być bezpiecznie używane w scenariuszach, takich jak dopasowywanie wzorców, argumenty atrybutów i współdziałanie z funkcjami zewnętrznymi.

Na przykład próba przypisania wyniku funkcji do literału zakończy się niepowodzeniem:

[<Literal>]
let yFunc() = "a" + "b" // error FS0267: this is not a valid constant expression

To rozróżnienie ma również znaczenie podczas wywoływania funkcji zewnętrznej . Na przykład DllImport jest atrybutem, który musi znać wartość myDLL podczas kompilacji. Bez deklaracji [<Literal>] ten kod nie może skompilować:

[<Literal>]
let myDLL = "foo.dll"

[<DllImport(myDLL, CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()

W wyrażeniach dopasowywania wzorców identyfikatory rozpoczynające się od małych liter są zawsze traktowane jako zmienne, które mają być powiązane, a nie jako literały, dlatego podczas definiowania literałów należy zazwyczaj używać początkowych liter.

[<Literal>]
let SomeJson = """{"numbers":[1,2,3,4,5]}"""

[<Literal>]
let Literal1 = "a" + "b"

[<Literal>]
let FileLocation =   __SOURCE_DIRECTORY__ + "/" + __SOURCE_FILE__

[<Literal>]
let Literal2 = 1 ||| 64

[<Literal>]
let Literal3 = System.IO.FileAccess.Read ||| System.IO.FileAccess.Write

Przykład zwięzłego dopasowywania wzorca przy użyciu nazwanych literałów

Literały nazwane mogą sprawić, że dopasowanie wzorca będzie bardziej zwięzłe, unikając konieczności klauzuli when lub dodatkowej logiki. Na przykład:

[<Literal>]
let ErrorCode = 404

let handleResponse code =
    match code with
    | ErrorCode -> "Not Found"
    | _ -> "Other Response"

Uwagi

Nazwane literały są przydatne w następujących celach:

  • Dopasowywanie wzorca bez klauzuli when.
  • Argumenty atrybutów.
  • Argumenty dostawcy typu statycznego.

Ciągi Unicode mogą zawierać jawne kodowanie, które można określić przy użyciu \u, a następnie 16-bitowy kod szesnastkowy (0000 — FFFF) lub kodowania UTF-32, które można określić przy użyciu \U, a następnie 32-bitowy kod szesnastkowy, który reprezentuje dowolny punkt kodu Unicode (000000000 – 0010FFFF).

Użycie operatorów bitowych innych niż ||| nie jest dozwolone.

Liczby całkowite w innych bazach

Podpisane 32-bitowe liczby całkowite można również określić w systemie szesnastkowym, ósemkowym lub binarnym, używając odpowiednio prefiksu 0x, 0o lub 0b.

let numbers = (0x9F, 0o77, 0b1010)
// Result: numbers : int * int * int = (159, 63, 10)

Podkreślenia w literałach liczbowych

Cyfry można oddzielić znakiem podkreślenia (_).

let value = 0xDEAD_BEEF

let valueAsBits = 0b1101_1110_1010_1101_1011_1110_1110_1111

let exampleSSN = 123_45_6789

Specjalne wartości nieskończoności zmiennoprzecinkowych

Zarówno float, jak i single typy liczb zmiennoprzecinkowe mają skojarzone specjalne wartości reprezentujące nieskończoność dodatnią i ujemną.

Wartość F# Typ języka F# Odpowiadająca wartość .NET
infinity lub +infinity float PositiveInfinity
-infinity float NegativeInfinity
infinityf lub +infinityf single PositiveInfinity
-infinityf single NegativeInfinity

Te wartości mogą być używane bezpośrednio lub są zwracane podczas dzielenia przez zero zmiennoprzecinkowe lub liczbę zbyt małą, aby być reprezentowane przez dany typ. Na przykład:

> 1.0/0.0;;
val it: float = infinity

> 1.0/(-0.0);;
val it: float = -infinity

> 1.0/0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
;;
val it: float = infinity